深入理解閉包(三)——確定this指向

原文地址:深入理解閉包(三)——確定this指向

我們在前面說過,在執(zhí)行上下文創(chuàng)建過程中做了三件事:創(chuàng)建變量對象,生成作用域鏈,確定this指向。今天我們就來探討一下this指向的問題。首先先回顧一下我們執(zhí)行上下文的生命周期圖:


執(zhí)行上下文是函數(shù)被調(diào)用時創(chuàng)建的,創(chuàng)建過程包括確定this指向,所以this的指向是在函數(shù)被調(diào)用時確定的。

我們知道,this對象是在運行時基于函數(shù)的執(zhí)行環(huán)境綁定的:在全局環(huán)境中,this指向window,當(dāng)函數(shù)被作為某個對象的方法調(diào)用時,this指向那個對象。不過實際情況中往往沒有那么好判斷,今天我們就來梳理一下。

全局對象中的this

在全局環(huán)境下,this永遠(yuǎn)指向window。

    console.log(this);    //window

函數(shù)中的this

this指向調(diào)用這個函數(shù)的對象。

    var a = 10;
    function test() {
        var a = 20;
        console.log(this.a);
    }
    test();   //10

由于函數(shù)test是被全局對象(window)調(diào)用的,因此函數(shù)內(nèi)部的this指向window。

    var a = 20;
    var obj = {
        a: 10,
        b:this.a,
        fn: function () {
            return this.a;
        }
    }

    console.log(obj.fn());   //10
    console.log(obj.b);      //20

由于函數(shù)fn是被對象obj調(diào)用的,因此函數(shù)fn內(nèi)部的this指向?qū)ο髈bj。
另外,由于obj不是個函數(shù),不適合上面的規(guī)則,我們要單獨討論,如果obj對象在全局創(chuàng)建,那么obj里面的this指向window。

構(gòu)造函數(shù)

構(gòu)造函數(shù)和其他函數(shù)的唯一區(qū)別,就是他們的調(diào)用方式不同。任何函數(shù),只要通過new操作符來調(diào)用,那它就可以作為構(gòu)造函數(shù),調(diào)用時經(jīng)歷以下四個步驟:

  1. 創(chuàng)建一個新對象;
  2. 將構(gòu)造函數(shù)的作用域賦給新對象(因此this就指向了這個新對象);
  3. 執(zhí)行構(gòu)造函數(shù)中的代碼(為這個新對象添加屬性);
  4. 返回新對象。
    function Test() {
        this.a = 1;
        console.log(this.a);      //1
    }
    var fun = new Test();
    console.log(fun.a);          //1

創(chuàng)建新對象new Test()后,this指向這個新對象,然后為這個新對象添加屬性a = 1,再執(zhí)行console.log(this.a),此時輸出的就是剛添加的a值。返回這個新對象傳遞給了實例對象fun,此時this指向了實例fun,因此fun.a也為1。

函數(shù)用call或apply調(diào)用

我們可以利用call或apply手動設(shè)置this的指向,這兩個方法的第一個參數(shù)都是this將要指向的對象,后面的參數(shù),都是向?qū)⒁獔?zhí)行的函數(shù)傳遞參數(shù)。其中call以一個一個的形式傳遞,apply以數(shù)組的形式傳遞,這是他們唯一的不同。

    var obj = {
        num: 10
    }
    function test(a, b) {
        console.log(this.num + a + b);
    }
    test(20,30);                    //NaN
    test.call(obj, 20, 30);        // 60
    test.apply(obj, [20, 30]);     // 60

這個例子很容易理解,本來調(diào)用test函數(shù)this指向全局對象,是無法訪問到obj對象中的num的,但是利用call和apply方法將this指向了obj對象,所以可以順利輸出。

以上就是我目前知道的關(guān)于this指向的幾種情況,以后可能會再補(bǔ)充。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容