実例解析javascriptの中のthis
2910 ワード
thisキーワードはJavascriptの中で最も複雑なメカニズムの一つです.thisの主な理解は、thisでのバインディングオブジェクトを知ることである.面接においても、プロジェクト開発においても、thisの習得は不可欠です.話は多くないです.まず例を見てみます.デフォルトのバインディングと暗黙のバインディング.デフォルトのバインディングはグローバル変数にthisを結びつけるものですが、厳密なモードは例外的で、thisはundefinedにバインドされます.デフォルトのバインディングの場合:独立関数呼び出し、匿名関数. 暗黙的なバインディングの場合、関数呼び出し中のthisは、「抱擁」または「包含」という関数のオブジェクトコンテキストに結びつけられます.暗黙的に失われた場合、thisはまたデフォルトのバインディングを適用します.したがって、上記の例では、オブジェクトobjに関数getName()を宣言した.Obj.get Name()を呼び出した時、この時はObjオブジェクトがそれを持っていますので、そのthisはObjに結び付けられました.つまり、この時(1)のthis.name=obj.nameです.そして、呼び出された後に匿名関数が返されます.だからobj.get Name();匿名関数を実行させ、このとき(2)のthisをwindowに結びつけると、「global name」が出力されます. 私たちが再び一つのgetName 2を定義すると、それは実際にはObj.getNameの参照であり、実際にはそれはgetName関数だけを参照しています.この時のgetName 2は、実際には修飾されていない関数として呼び出されています.したがって、デフォルトのバインディング、すなわち暗黙的な損失を適用しました.上の例に続いて、もう2つの関数を実行します.
OKです.じゃ続けます.
随堂テストです
//"use strict";
var name = "global name";
var obj = {
name:"obj name",
getName: function(){
console.log(this.name); //(1)
return function(){
console.log(this.name); //(2)
}
}
}
//
obj.getName()(); // "obj name" "global name"
var getName2 = obj.getName;
getName(); // "global name" "global name"
注:標準モードでは上の出力ですが、厳格モードでは(2)TypeError:Canot read property'name'of undefinedをエラーします.この例には主に二つのthisのポイントがあります.getName2().call(obj); //"global name" "obj name"
(getName2.call(obj))(); //"obj name" "global name"
コールの使い方に詳しい人なら、正しい答えが出せるはずです.これがthisの第三のポイントです.顕式結合です.すなわち関数は、call(...)とappy(...)の方法を使用して、thisのバインディングオブジェクトを指定することができます.get Name 2().call(obj)すなわち、コールバック関数のthis表示をobjに結びつけることに相当するので、第二の出力はobj.nameとなる.get Name 2.cal(obj)get Name 2のthisをobjに結びつけることに相当するので、(get Name 2.cal(obj)();とobj.get Name();等価ですOKです.じゃ続けます.
var a;
function foo(a){
this.a = a;
}
foo(1);
var bar = new foo(2);
console.log(a); //1
console.log(bar.a); //2
emmは上のような結果がよく分かります.しかし、これはthisバインディングの第4のルールです.newバインディングです.ついでに、newを使って関数を呼び出したり、コンストラクターの呼び出しがあった場合、自動的に実行されます.1)全く新しいオブジェクトを作成(構築)する.2)この新しいオブジェクトは[prototype]接続されます.3)この新しいオブジェクトは、関数で呼び出されたthisに結合されます.4)関数が他のオブジェクトに戻っていない場合、new式の関数呼び出しは自動的にこの新しいオブジェクトに戻ります.最後に4つのバインディングの優先度:newバインディング>明示的>暗黙的>デフォルト随堂テストです
// 1
function foo(){
console.log(this.a);
}
var obj2 = {
a:1,
foo:foo
};
var obj1 = {
a:2,
obj2:obj2
};
obj1.obj2.foo(); //1
// 2
function foo(){
console.log(this.a);
}
function doFoo(fn){
fn();
}
var obj = {
a:2,
foo:foo
};
var a = "global";
doFoo(obj.foo); // "global"
// , var fn = obj.foo; fn();
// 3
function foo(){
console.log(this.a);
}
var obj1 = {
a:1,
foo:foo
};
var obj2 = {
a:2,
foo:foo
};
obj1.foo(); //1
obj2.foo(); //2
obj1.foo.call(obj2); //2
obj2.foo.call(obj1); //1