このjavascriptキーワード-実際にコンテキストを定義することを学ぶ

一部の読者の要請で、javascriptでコンテキストに関するトピックを書くことにしました。 JavaScriptの初心者は、JavaScriptのthisキーワードの意味をよく理解していません。 このトピックは、初心者だけでなく、記憶の中でこの側面をリフレッシュしたいだけの人にとっても興味深いものになります。 以下の例を参照してください。 少なくとも1つのポイントで「ログに表示される内容」という質問に答えるのに迷っている場合、または単に答えを見たい場合は、catにようこそ。

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


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メソッドを使用すると、実行中の関数のコンテキストを設定できます。 applycallの違いは、パラメーターが関数に渡される方法のみです。 両方の関数の最初のパラメーターは、関数のコンテキスト(これが等しくなるもの)を決定します。

適用/呼び出しの違い
 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


この記事では、 このキーワードがJavaScriptでどのように機能するかを説明しようとしました。 近い将来、これらの微妙な点を知っておく必要がある理由を説明する記事(たとえば、jQuery.proxy)を書くことになるでしょう。

PSエラー/不正確に気づいた場合、または何かを明確化/追加したい場合-PMに書き込み、修正します。

Source: https://habr.com/ru/post/J149516/


All Articles