js 關(guān)于this的指向

一、先看個(gè)函數(shù)調(diào)用例子

例子來源https://blog.csdn.net/Rainy_X/article/details/80022684

    function Foo() {
        getName = function () { alert(1); };
        return this;
    }
    Foo.getName = function () { alert(2); };
    Foo.prototype.getName = function () { alert(3); };
    var getName = function () { alert(4); };
 
    Foo.getName();  // ------- 輸出 2 -------
    // 調(diào)用 Foo函數(shù) 作為 對(duì)象 動(dòng)態(tài)添加的屬性方法 getName
    // Foo.getName = function () { alert(2); };
 
    getName();      // ------- 輸出 4 -------
    // 這里 Foo函數(shù) 還沒有執(zhí)行,getName還沒有被覆蓋
    // 所以 這里還是 最上面的 getName = function () { alert(4); };
 
    Foo().getName();    // ------- 輸出 1 -------
    // Foo()執(zhí)行,先覆蓋全局的 getName 再返回 this,
    // this 是 window, Foo().getName() 就是調(diào)用 window.getName
    // 此時(shí) 全局的 getName已被覆蓋成 function () { alert(1); };
    // 所以 輸出 1
    /* 從這里開始 window.getName 已被覆蓋 alert 1 */
 
    getName();  // -------- 輸出 1 --------
    // window.getName alert(1);
 
    new Foo.getName();     // ------- 輸出 2 -------
    // new 就是 找 構(gòu)造函數(shù)(),由構(gòu)造函數(shù)結(jié)合性,這里即使 Foo無參,也不能省略 (),所以不是 Foo().getName()
    // 所以 Foo.getName 為一個(gè)整體,等價(jià)于 new (Foo.getName)();
    // 而 Foo.getName 其實(shí)就是函數(shù) function () { alert(2); } 的引用
    // 那 new ( Foo.getName )(), 就是在以 Foo.getName 為構(gòu)造函數(shù) 實(shí)例化對(duì)象。
    // 就 類似于 new Person(); Person 是一個(gè)構(gòu)造函數(shù)
 
    // 總結(jié)來看 new ( Foo.getName )(); 就是在以 function () { alert(2); } 為構(gòu)造函數(shù)來構(gòu)造對(duì)象
    // 構(gòu)造過程中 alert( 2 ),輸出 2
 
    new Foo().getName();    // ------- 輸出 3 -------
    // new 就是 找 構(gòu)造函數(shù)(),等價(jià)于 ( new Foo() ).getName();
    // 執(zhí)行 new Foo() => 以 Foo 為構(gòu)造函數(shù),實(shí)例化一個(gè)對(duì)象
    // ( new Foo() ).getName; 訪問這個(gè)實(shí)例化對(duì)象的 getName 屬性
    // 實(shí)例對(duì)象自己并沒有 getName 屬性,構(gòu)造的時(shí)候也沒有 添加,找不到,就到原型中找
    // 發(fā)現(xiàn) Foo.prototype.getName = function () { alert(3); };
    // 原型中有,找到了,所以 ( new Foo() ).getName(); 執(zhí)行,alert(3)
 
    var p = new new Foo().getName();     // ------- 輸出 3 -------
    // new 就是 找 構(gòu)造函數(shù)(),等價(jià)于 new ( ( new Foo() ).getName )() 輸出 3
 
    // 先看里面的 ( new Foo() ).getName
    // new Foo() 以Foo為構(gòu)造函數(shù),實(shí)例化對(duì)象
    // new Foo().getName 找 實(shí)例對(duì)象的 getName屬性,自己沒有,去原型中找,
    // 發(fā)現(xiàn) Foo.prototype.getName = function () { alert(3); }; 找到了
 
    // 所以里層 ( new Foo() ).getName 就是 以Foo為構(gòu)造函數(shù)實(shí)例出的對(duì)象的 一個(gè)原型屬性
    // 屬性值為一個(gè)函數(shù) function () { alert(3); } 的引用
 
    // 所以外層 new ( (new Foo()).getName )()在以該函數(shù) function () { alert(3); } 為構(gòu)造函數(shù),構(gòu)造實(shí)例
    // 構(gòu)造過程中 執(zhí)行了 alert(3), 輸出 3
二、 自執(zhí)行函數(shù)(匿名函數(shù))

每個(gè)函數(shù)在調(diào)用時(shí),都會(huì)去獲取2個(gè)值: arguments和this。
匿名函數(shù)在獲取這2個(gè)值時(shí),只會(huì)搜索自己執(zhí)行環(huán)境中的,永遠(yuǎn)不會(huì)直接訪問外部函數(shù)或執(zhí)行環(huán)境中的這2個(gè)變量。
匿名函數(shù)是一個(gè)沒有指針的全局變量,它的執(zhí)行環(huán)境具有全局性,所以它的this指向的就是全局window對(duì)象

(function(){
console.log(this);//this指向的是window
})();
三、 定時(shí)器中的函數(shù)

定時(shí)器中的函數(shù)和匿名函數(shù)一樣(沒有默認(rèn)的宿主對(duì)象),所以默認(rèn)this指向window,如果想要在setTimeout/setInterval中使用這個(gè)對(duì)象的this引用,可以使用如 _this = this保存this指針

var obj = {
   func: function() { 
             console.log("123")
         },
   say: function () {
          var _this = this;   //此時(shí)的this就是obj對(duì)象
          setTimeout(function () {
             console.log(this)   // window
             _this.func()  // "123"
          });
   }
 }
 obj.say();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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