javascript 下的 this,讓你猜不透,摸不著,但語法終究有語法的規範,沒有莫名的奇妙,只有欠合理的解釋。對還有 bug … 開玩笑 ^-^///
不多說,這章來討論一下 javascript 下的 this 。
此前先仔細體會這句話:this永遠指向的是最後呼叫它的物件。
由於其執行期繫結的特性,this的指向在函式定義的時候是確定不了的,只有函式執行的時候才能確定this到底指向誰。
window 下的 this:
看幾個例子來解釋我上面強調的那句話:
function a(){
var num= 233;
console.log(this.user); //undefined
console.log(this); //Window
}
a();
執行結果是 this指向的是 window ,所以 this.user 是 undefined,a()
是 一個函式也可以說是方法 ,那方法肯定是由物件來呼叫
的。
所以當執行 a()
; 時 就有一個隱式物件呼叫了a()
,這個隱式物件就是 window
再來個例子:
var obj = {
num: 233,
getThis:function () {
return this;
}
}
console.log(obj.getThis() ); //{ num: 233, getThis: [Function] }
var fun = obj.getThis;
console.log(fun() ); // window
上面是一個物件裡面有方法屬性;
可以看出 obj.getThis() ;
呼叫方法會列印出當前物件(列印日誌裡面有屬性和方法);
可能大家回想,這不是常理之中嗎,但下面這程式碼我只是做了一些賦值結果怎麼就不一樣了呢?
var fun = obj.getThis;
console.log(fun() ); // window
因為 執行fun()
是一個方法,需要物件才能呼叫方法,而上面執行 fun()
的物件是誰,就是隱式的 window
(這句話好像上面第一段程式碼說過 -_-///),
好了,如果還感覺有點繞就來說明一下:
this永遠指向的是最後呼叫它的物件。
obj.getThis()
其中 呼叫 getThis()
的 物件是誰? obj
,所以 返回的this
就是 obj。
那 console.log( fun() );
其中 呼叫 fun()
的物件是誰,沒誰呼叫啊? 沒誰那就是隱式的 window
啦 ,所以返回的是 window
,看哪個最後呼叫它,那麼this
就指向那個。
上面清楚了來分析下面這段程式碼應該就容易了:
num_1 = 233;
var obj = {
num_2: 1111,
getNum:function () {
this.num_1 = 666;
this.fun = function () {
return this.num_1;
}
}
}
obj.getNum();
console.log(obj.fun() ); // 666
var fun = obj.fun;
console.log( fun() ); // 233
先執行了 obj.getNum();
對 getNum()
裡面的 屬性和方法進行賦值;
接著 執行 obj.fun()
, 因為 裡面的 this
指向呼叫它的 obj
,所以 得到num_1 = 666;
再接著執行 fun()
,因為 呼叫這方法的是隱式 window
,所以 this.num_1; 就會找到 在window宣告的遍歷 num_1 = 233;
當遇到包含物件的問題:
var obj = {
a:233,
obj_2:{
a:666,
fn:function(){
console.log(this.a); // 666
}
}
}
obj.obj_2.fn();
也很好解釋 ,找到呼叫 fn() 函式的物件 是 obj_2, 所以 this 指向 obj_2。
當 this 碰到 return 時:
例子1:
function fun()
{
this.num= 233;
return {};
}
var a = new fun();
console.log(a.num); //undefined
例子2:
function fun()
{
this.num= 233;
return 11;
}
var a = new fun();
console.log(a.num); //233
總結一句話 : 如果返回值是一個物件,那麼this指向的就是那個返回的物件,如果返回值不是一個物件那麼this還是指向函式的例項。
當 this 遇到 apply() 和 call()
例子1 :
function AddNum(a,b){
this.a = a;
this.b = b;
this.fun = function ( ) {
return this.a + this.b;
}
}
var obj = new AddNum(1,2);
console.log( obj.fun() ); // 3
var obj_2 = {a:2,b:4};
console.log( obj.fun.call(obj_2) ); // 6
當執行 obj.fun.call(obj_2); fun() 的this 就指向 obj_2,所以this.a + this.b;拿到的也是 obj_2 下的 a 和 b ;
apply() 和 call() 能 改變 this 的 指標