var f = function() { this.x = 5; (function() { this.x = 3; })(); console.log(this.x); }; var obj = {x: 4, m: function() { console.log(this.x); }}; f(); new f(); obj.m(); new obj.m(); f.call(f); obj.m.call(f);
せっかちな人への答え
3
5
4
未定義
5
5
5
4
未定義
5
5
1.理論
他の多くのプログラミング言語とは異なり、javascriptのthisキーワードはオブジェクトにバインドされていませんが、呼び出しのコンテキストに依存します。 理解を簡単にするために、グローバルオブジェクトがウィンドウであるブラウザに関連する例を検討します。
1.1。 単純な関数呼び出し
function f() { console.log(this === window); // true } f();
この場合、関数f内のthisはグローバルオブジェクトと同じです(たとえば、ブラウザではwindow 、Node.jsではglobal )。
自己呼び出し関数は、まったく同じ原理で機能します。
(function () { console.log(this === window); // true })();
1.2。 コンストラクター内
function f() { this.x = 5; console.log(this === window); // false } var o = new f(); console.log(ox === 5); // true
newキーワードを使用して関数を呼び出す場合、関数はコンストラクターとして機能し、この場合、作成されるオブジェクトを指します。
1.3。 オブジェクトメソッド内
var o = { f: function() { return this; } } console.log(of() === o); // true
関数がオブジェクトのプロパティとして実行される場合、 これはこのオブジェクトを参照します。 この関数がオブジェクトのどこから来たのかは問題ではありません。主なことは、それがどのように呼び出され、どのオブジェクトが関数呼び出しの前にあるかです:
var o = { f: function() { return this; } } var o2 = {f: of}; console.log(of() === o);//true console.log(o2.f() === o2);//true
1.4。 適用、メソッドの呼び出し
applyメソッドとcallメソッドを使用すると、実行中の関数のコンテキストを設定できます。 applyとcallの違いは、パラメーターが関数に渡される方法のみです。 両方の関数の最初のパラメーターは、関数のコンテキスト(これが等しくなるもの)を決定します。
適用/呼び出しの違い
function f(a,b,c) { return a * b + c; } f.call(f, 1, 2, 3); // ; var args = [1,2,3]; f.apply(f, args); // // ; // <b>f</b> a = 1, b = 2, c = 3;
例:
function f() { } f.call(window); // this f window f.call(f); //this f f
より簡単:
function f() { console.log(this.toString()); // 123 } f.call(123); // this f Number 123
2.タスクを分析します
取得した知識をトピックの冒頭で与えられた問題に適用します。 繰り返しになりますが、簡単にするために、グローバルオブジェクトがウィンドウであるブラウザに関連する例を検討します。
2.1。 f()
var f = function() { // f - f(), // this this.x = 5; // window.x = 5; // 1.1 , this (function() { this.x = 3; // window.x = 3 })(); console.log(this.x); // console.log(window.x) };
結果: 3
2.2。 new f();
var f = function() { // f new, // this ( object) this.x = 5; // object.x = 5; // 1.1 , this (function() { this.x = 3; // window.x = 3 })(); console.log(this.x); // console.log(object.x) };
結果: 5
2.3。 obj.m();
var obj = {x: 4, m: function() { // 1.3 , this === obj, console.log(this.x); // console.log(obj.x) } };
結果: 4
2.4。 new obj.m();
var obj = {x: 4, m: function() { // 1.2 , this // this.x, - undefined console.log(this.x); } };
結果:未定義
2.5。 f.call(f);
var f = function() { // f call // call ( ) f, // this f this.x = 5; // fx = 5; // 1.1 , this (function() { this.x = 3; // window.x = 3 })(); console.log(this.x); // console.log(fx) };
結果: 5
2.6。 obj.m.call(f);
var obj = {x: 4, m: function() { // call // f // this f // fx 5, 5 console.log(this.x); // console.log(fx) } };
結果: 5
重要:この例を残りとは別に検討すると、ログは5ではなく未定義になります。 例をよく解析して、動作を説明してください。
var f = function() { this.x = 5; (function() { this.x = 3; })(); console.log(this.x); }; var obj = {x: 4, m: function() { console.log(this.x); }}; obj.m.call(f);
結論の代わりに
すべて一緒に答える
3
5
4
未定義
5
5
5
4
未定義
5
5
この記事では、 このキーワードがJavaScriptでどのように機能するかを説明しようとしました。 近い将来、これらの微妙な点を知っておく必要がある理由を説明する記事(たとえば、jQuery.proxy)を書くことになるでしょう。
PSエラー/不正確に気づいた場合、または何かを明確化/追加したい場合-PMに書き込み、修正します。