JS矢印文法及び矢印関数this方向の問題
7102 ワード
原文のまとめと補充
Funebug
この文章の著作権は元の作者の所有になります.翻訳は勉強だけに使います.
本論文では矢印関数の利点を紹介します.
より簡潔な文法はまず従来の文法によって関数を定義します.
じゃ、私たちはどうやってこの問題を解決しますか?矢印関数を使用します.矢印関数を使用すると、全体のオブジェクトにthisが結合されないようになります.
先の説を検証するために、Counter関数のthisをthatに結び付けて、set Intervalでthisとthatが同じかどうかを判断します.
clear Interval(b.timer)
;() => { }
:P => { }
;
, return ;P => num;
this ;
call apply this, ;
constructor;
argument , argument ;
JavaScript:Arrow Functions for BeginersFunebug
この文章の著作権は元の作者の所有になります.翻訳は勉強だけに使います.
本論文では矢印関数の利点を紹介します.
より簡潔な文法はまず従来の文法によって関数を定義します.
function funcName(params) {
return params + 2;
}
funcName(2);
// 4
この関数は矢印関数を使って、1行のコードだけで済ませることができます.var funcName = (params) => params + 2
funcName(2);
// 4
かっこいいですか極端に簡潔な例ですが、コードを書く際の矢印関数の利点をよく表しています.矢印関数の文法を深く理解します.(parameters) => { statements }
パラメータがない場合は、さらに簡略化することができる.() => { statements }
パラメータが一つしかない場合は、括弧を省略できます.parameters => { statements }
戻り値が1つの表式だけであれば、大かっこは省略できます.parameters => expression
// :
function (parameters){
return expression;
}
矢印の文法はもう覚えました.実戦でやりましょう.Chromeブラウザ開発者コンソールを開き、入力:var double = num => num * 2
変数doubleを矢印関数に結びつけ,この関数にはパラメータnumがあり,num*2に戻る.この関数を呼び出す:double(2);
// 4
double(3);
// 6
局所的なthisがないバインディングと一般的な関数は異なり、矢印関数はthisをバインディングしません.矢印関数は、元のバインディングを変更しません.一例を使って説明します.function Counter() {
this.num = 0;
}
var a = new Counter();
キーワードnew構造を使用したので、Count()関数のthisは新しいオブジェクトに結合され、aに値を与えます.consolie.logでa.numを印刷して0を出力します.console.log(a.num);
// 0
もし私達が一秒ごとにa.numの値をプラスしたいなら、どうやって実現しますか?set Interval()関数が使用できます.function Counter() {
this.num = 0;
this.timer = setInterval(function add() {
this.num++;
console.log(this.num);
}, 1000);
}
出力結果を見てみます.var b = new Counter();
// NaN
// NaN
// NaN
// ...
一秒ごとに累積した数字ではなくNaNが印刷されていることが分かります.いったいどこが間違っていますか?まず次のような文を使ってsetInterval関数の連続実行を停止します.clearInterval(b.timer);
なぜ間違えたのかを理解してみます.前のブログで説明した規則によると、まず関数setIntervalはある声明の対象に呼び出されていません.newキーワードも使っていません.set Intervalはただ普通の関数です.実際にset Intervalの中のthisは大域のオブジェクトに結び付けられています.私たちはthisをプリントアウトして確認できます.function Counter() {
this.num = 0;
this.timer = setInterval(function add() {
console.log(this);
}, 1000);
}
var b = new Counter();
すべてのwindowオブジェクトが印刷されていることが分かります.次のコマンドで印刷を停止します.clearInterval(b.timer);
前の関数に戻ってNaNをプリントするのは、this.numがwindowオブジェクトのnumに結び付けられているからです.window.numは定義されていません.じゃ、私たちはどうやってこの問題を解決しますか?矢印関数を使用します.矢印関数を使用すると、全体のオブジェクトにthisが結合されないようになります.
function Counter() {
this.num = 0;
this.timer = setInterval(() => {
this.num++;
console.log(this.num);
}, 1000);
}
var b = new Counter();
// 1
// 2
// 3
// ...
Counterコンストラクタによって結合されたthisは保存されます.set Interval関数では、thisは依然として私たちが新しく作成したbオブジェクトを指しています.先の説を検証するために、Counter関数のthisをthatに結び付けて、set Intervalでthisとthatが同じかどうかを判断します.
function Counter() {
var that = this;
this.timer = setInterval(() => {
console.log(this === that);
}, 1000);
}
var b = new Counter();
// true
// true
// ...
私たちが望むように、プリントの値は毎回trueです.最後に、スクリーン印刷を終了します.clear Interval(b.timer)
要約矢印関数の記述コードはより簡潔な文法を持っています.thisは結合されません.