JavaScriptの中のthisについて話します.
3528 ワード
JavaScriptの中のthisはいつも比較的に人に頭が痛くて、面接試験の特に聞きやすい問題です.以下はこの「知らないJavaScript」を参照して、thisという不思議なものを勉強します.
thisは何処を指していますか?
thisは、実行中にバインディングされており、作成時にバインディングされていません.コンテキストは、関数呼び出し時の様々な条件に依存します.thisの結合と関数宣言の位置は関係なく、関数の呼び出しに依存します.
したがって、thisは単に関数やオブジェクト自体を指すのではない.
thisの4つの結合方式
標準バインディング
デフォルトのバインディングとは、thisのデフォルトのバインディングです.
暗黙的バインディングとは、において、 は、コールバック関数においても、実はthisバインディングが失われている場合があります.コールバック関数obj.fooは、foo関数を参照しています.objオブジェクトとは関係ありません.
明示的なバインディングとは、call、apply、bindを使用して、あるコンテキストを指定してバインディングすることであり、それらの一つの役割は、関数のためだけにコンテキストオブジェクトをハードバインドすることである.
以前のコールバック関数はビッドを使って修正した後、私達のobjオブジェクトのa属性を印刷しました.
newバインディング
newキーワードを使ってオブジェクトを作成するプロセスは、コンテキストを結合するプロセスでもありますので、newを使って作成したオブジェクトのthisも特に注意してください.
newを使って関数を呼び出すか、またはコンストラクターの呼び出しが発生した場合、自動的に次の操作が実行されます.新しいオブジェクトを作成(または構造)します. この新しいオブジェクトは[プロトタイプ]に接続されます. この新しいオブジェクトは、関数呼び出しのthisに結合されます. 関数が他のオブジェクトに戻っていない場合、new式の関数呼び出しは自動的にこの新しいオブジェクトに戻ります.
thisの4つのバインディング方式の並べ替え
4つの結合がすべてthisの方向を変えることができるなら、この4つの結合の優先度はどうなりますか?結論は:
矢印関数
thisについて最後に言いたいのはES 6の矢印関数です.
これは実際には、現在のthisコンテキストをスコープで保存して、コールバック関数に伝達します.本質的にはthisの元からある機構を捨てたのです.
最後に
私たちは四つのよくあるthis結合方式と矢印関数の二つの角度システムからthis結合の知識点を学びました.これからはthis関連の知識点が怖くないと信じています.
この文章にはまだ改善できるところがたくさんあります.もし何か意見や問題があれば、コメントで指摘してください.ありがとうございます
おすすめ資料あなたが知らないJavaScript(上巻) Know this、use this!(thisの一般的な使い方をまとめます)
thisは何処を指していますか?
thisは、実行中にバインディングされており、作成時にバインディングされていません.コンテキストは、関数呼び出し時の様々な条件に依存します.thisの結合と関数宣言の位置は関係なく、関数の呼び出しに依存します.
したがって、thisは単に関数やオブジェクト自体を指すのではない.
thisの4つの結合方式
標準バインディング
デフォルトのバインディングとは、thisのデフォルトのバインディングです.
function foo() {
console.log(this.a)
}
var a = 3;
foo(); // 3
注意:厳密なモードでは、このデフォルトのバインディング形式は成立しません.var a = 3;
function foo() {
"use strict";
console.log(this.a)
}
foo(); // TypeError
陰式バインディング暗黙的バインディングとは、
obj.foo();
のように、this所在関数がコンテキストで結合されていることを意味する.function foo() {
console.log(this.a);
}
var a = 1;
var obj = {
a: 2,
foo: foo
};
obj.foo(); // 2
オブジェクトの関数は参照関係だけで、オブジェクトと関数は2つの場所に存在します.したがって、他の場所では関数を使用して、陰的に結合されたオブジェクトとは関係がありません.次の二つの例を参照してください.var myFoo = obj.foo
のmyFoo変数はfoo()関数を参照し、objとは関係がない.したがって、myFooの実行関数挙動はデフォルトバインディングとなり、印刷結果は1となります.function foo() {
console.log(this.a);
}
var a = 1;
var obj = {
a: 2,
foo: foo
};
var myFoo = obj.foo
myFoo(); // , 1
function foo() {
console.log(this.a);
}
var a = 1;
var obj = {
a: 2,
foo: foo
};
setTimeout(obj.foo, 300); // 1
バインディングを表示明示的なバインディングとは、call、apply、bindを使用して、あるコンテキストを指定してバインディングすることであり、それらの一つの役割は、関数のためだけにコンテキストオブジェクトをハードバインドすることである.
以前のコールバック関数はビッドを使って修正した後、私達のobjオブジェクトのa属性を印刷しました.
function foo() {
console.log(this.a);
}
var a = 1;
var obj = {
a: 2,
foo: foo
};
setTimeout(obj.foo.bind(obj), 300);
callとappyも同様で、関数にコンテキストを指定することによってハードバインディングを行い、ハードバインディングは一回のみとなります.call()
方法の役割は、apply()
方法と同様であり、call()
方法が許容するのはパラメータリストであり、apply()
方法が許容するのはパラメータ配列であるという違いがある.newバインディング
newキーワードを使ってオブジェクトを作成するプロセスは、コンテキストを結合するプロセスでもありますので、newを使って作成したオブジェクトのthisも特に注意してください.
newを使って関数を呼び出すか、またはコンストラクターの呼び出しが発生した場合、自動的に次の操作が実行されます.
function foo(a) {
this.a = a;
}
var bar = new foo(2);
console.log( bar.a ); // 2
new挙動の第三段階はthisバインディングを行うことであり,コードからnew挙動の確実な結合thisの能力を見ることもできる.thisの4つのバインディング方式の並べ替え
4つの結合がすべてthisの方向を変えることができるなら、この4つの結合の優先度はどうなりますか?結論は:
new > > >
いくつかのシーンを一つのthisに結びつけることはめったにないですが、念のためにも.矢印関数
thisについて最後に言いたいのはES 6の矢印関数です.
function foo() {
setTimeout(() => {
// this foo()
console.log(this.a);
}, 100);
}
var obj = {
a: 2
};
foo.call(obj); // 2
完全に同じです.function foo() {
var self = this; // lexical capture of this
setTimeout(function () {
console.log(self.a);
}, 100);
}
var obj = {
a: 2
};
foo.call(obj); // 2
矢印関数についてはvar self = this;
を覚えておけば十分です.これは実際には、現在のthisコンテキストをスコープで保存して、コールバック関数に伝達します.本質的にはthisの元からある機構を捨てたのです.
最後に
私たちは四つのよくあるthis結合方式と矢印関数の二つの角度システムからthis結合の知識点を学びました.これからはthis関連の知識点が怖くないと信じています.
この文章にはまだ改善できるところがたくさんあります.もし何か意見や問題があれば、コメントで指摘してください.ありがとうございます
おすすめ資料