1. 基本概念
MDN の公式説明: 他の言語と比較して、JavaScript では関数の this キーワードの動作が若干異なります。厳密モードと非厳密モードのいくつかの違い。ほとんどの場合、関数の呼び出し方法によって this の値が決まります。 this は実行中に割り当てることができず、this の値は関数が呼び出されるたびに異なる可能性があります。
要約:
1. this が指すオブジェクトは、関数のコンテキスト オブジェクト context と呼ばれます;
2. this の指すことは、 function は呼び出されます
関数がどのように呼び出されても、これらの点を覚えていれば、この方向を明確に見つけることができます。
2. 小さな実験
function foo(){ console.log(this); }
面接官がこれがどこを指しているのか尋ねると、もちろんあなたは大声で「わかりません」と答えます。関数はまだ呼び出されておらず、それがどこを指しているのかはわかりません。
概要: 関数名を使用して関数を直接呼び出します。これはグローバル変数ウィンドウを指します。また、object.function 名を介して関数を呼び出します。これはオブジェクトを指します。
3. DOM オブジェクトが関数を呼び出すときのこのポインティングの問題
1. セレクターで要素を選択し、イベントをバインドするイベント属性を追加します。これは DOM オブジェクトをポイントします例は次のとおりです:
document.getElementById('btn').onclick=function(){ console.log('click'); //click console.log(this); //<button id="btn">button</button> }
2. イベントを DOM タグに直接書き込みます。これはウィンドウを指します。これをパラメータとしてメソッドに渡して使用できます。例は次のとおりです。
html: <button onclick="modify()">add</button> <span id="count">0</span> <button onclick="modify()">reduce</button> script: // 操作方法 function modify(){ console.log(this); //window }
メソッドはこの時点で直接呼び出されるので、これはグローバル ウィンドウ オブジェクトを指しているため、問題は、どのボタンをクリックしたかを確認したいのですが、どうすればよいでしょうか? this の値をパラメータとしてメソッドに渡して使用する例は次のとおりです。
html: <button onclick="modify(this)">add</button> <span id="count">0</span> <button onclick="modify(this)">reduce</button> script: // 操作方法 function modify(_this){ console.log(_this); // <button onclick="modify(this)">add</button> // <button onclick="modify(this)">reduce</button> }
4. オブジェクトにおける this の指摘する問題
最初に簡単な例を見てみましょう:
var a=1; function printA(){ console.log(this.a); } var obj={ a:2, foo:printA, bar:function(){ printA(); } } obj.foo(); //2 obj.bar(); //1var foo=obj.foo;foo(); //1
グローバル変数 a とグローバル変数メソッドを定義します。 a. を出力し、 a 属性と 2 つのメソッド foo および bar を含む obj オブジェクトを定義しました。 obj.foo() を呼び出すと 2 が出力され、obj.bar() を呼び出すと 1 が出力されます。
分析:
printA がどこで定義されているかに関係なく、ポイントはこれは、誰から呼び出されたかによってのみ決まります。 obj.foo() では、foo の属性値は printA で、obj によって直接呼び出されるので、this.a は obj を指し、this.a は obj.a=2;
obj を呼び出すときです。 bar() 、 bar の属性値は function(){printA()} です。どのオブジェクトが printA メソッドを呼び出すかは明確ではありません。これはデフォルトでグローバル オブジェクト ウィンドウを指すため、 this.a=window.a=1 ;
3 番目 この場合、obj.foo 値を foo 変数に割り当てます。これは、呼び出されたときの window.foo() と同等であり、1 を出力します。
要約: このポイントは関数宣言によって拘束されませんが、関数の実行中に動的に拘束されます。
5. このポインティング メソッドを変更します: app play call binding
あまり言うことはありません: 例を書きました。最初に見てみましょう。比喩が不適切な場合はご理解ください。意味はただそれだけです。
var liLei={ name:'liLei', money:10, buyPen:function(){ this.money=this.money-1; console.log(this.name+" have money:"+this.money) } } var hanMeiMei={ name:'hanMeiMei', money:20, buyPan:function(){ this.money=this.money-2; console.log(this.name+" have money:"+this.money) } } liLei.buyPen(); // liLei have money:9 hanMeiMei.buyPan(); //hanMeiMei have money:18
例は理解しやすく、出力結果は誰でも理解できると思います。ある日、ハン・メイメイは鍋を買おうとしましたが、彼女は「彼女はまだその方法を持っていなかったのでできませんでした。彼女は考えました:私はこの方法を持っていませんが、リー・レイは持っています。私はリー・レイに電話して、それを買ってくれるように頼みました。その後、リー・レイは、ディスク、方法は同じでした。では、それをコードに実装するにはどうすればよいでしょうか?
JavaScript には、call、apply、bind などの実装メソッドがいくつかあります。
callメソッド:
構文: call(thisObj, Object)
定義: オブジェクトのメソッドを呼び出し、現在のメソッドを別のメソッドに置き換えます。オブジェクトオブジェクト。
説明:
call メソッドを使用すると、別のオブジェクトの代わりにメソッドを呼び出すことができます。 call メソッドは、関数のオブジェクト コンテキストを初期コンテキストから thisObj で指定された新しいオブジェクトに変更します。 thisObj パラメータが指定されていない場合は、グローバル オブジェクトが thisObj として使用されます。
liLei.buyPen.call(hanMeiMei); //hanMeiMei have money:19 hanMeiMei.buyPan.call(liLei); //liLei have money:8
apply メソッド:
構文: apply(thisObj, [argArray])
定義: 特定のオブジェクトのメソッドを適用し、別のオブジェクトを使用しますオブジェクトは現在のオブジェクトを置き換えます。
注:
argArray が有効な配列でない場合、または引数オブジェクトではない場合、TypeError が発生します。 argArray も thisObj も指定されていない場合は、Global オブジェクトが thisObj として使用され、パラメータを渡すことはできません。
liLei.buyPen.apply(hanMeiMei); //hanMeiMei have money:19 hanMeiMei.buyPan.apply(liLei); //liLei have money:8
bind メソッド:
liLei.buyPen.bind(hanMeiMei)(); //hanMeiMei have money:19 hanMeiMei.buyPan.apply(liLei)(); //liLei have money:8
要約: 3 つのメソッドは同じ点を持っています: このポインタを変更できます。違いは、apply で受け入れられるパラメータは配列であり、 call で受け取るパラメータはそれぞれ独立した値で、apply と call はメソッドを直接呼び出し、bind は this のポインタを変更してメソッドを呼び出さずに返します。
推奨チュートリアル: js チュートリアル
以上がjs の This を指す問題の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。