javascript 下的 this

曾田生z發表於2016-09-01

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 的 指標

相關文章