(BTMST)js變量提升面試題解析

 ###變量提升綜合面試題
   function Foo() {
         getName = function(){ alert(1); };
         return this;
    }
    Foo.getName = function() { alert(2); };
    Foo.prototype.getName = function(){ alert(3); };
    var getName = function() { alert(4); };
    function getName(){ alert(5); }


    Foo.getName(); // ?
    getName(); // ?
    Foo().getName(); // ?
    getName(); // ?
    new Foo.getName(); // ?
    new Foo().getName(); // ?
    new new Foo().getName(); // ?  

第一眼看到這個(gè)題目我是一臉蒙蔽,感覺(jué)無(wú)處下手~~(╯﹏╰)b,沒(méi)辦法啊,一步一步來(lái),好在最后把這個(gè)東西給搞定了。下面來(lái)說(shuō)說(shuō)解題思路。
*解題步驟:
1.解變量提升題,如果第一眼不能快速得出答案,建議根據(jù)變量提升的原則分析出js變量提升后的代碼

//變量提升后
    //1.函數(shù)整體提升
     function Foo() {
         getName = function(){ alert(1); };
         return this;
    }

    //2.同名函數(shù)和變量,函數(shù)提升,變量忽略聲明
    function getName(){ alert(5); }

    //其他的不變
    Foo.getName = function() { alert(2); };
    Foo.prototype.getName = function(){ alert(3); };
    getName = function() { alert(4); };

2.變量提升后,我們發(fā)現(xiàn)情況并不明朗,只能畫(huà)個(gè)圖了

Paste_Image.png
全局Foo構(gòu)造函數(shù):Foo.getName = function() { alert(2); };
Foo原型:Foo.prototype.getName = function(){ alert(3); };
全局getName函數(shù):getName = function() { alert(4); };(后賦值將前值覆蓋)

3.開(kāi)始解題
第一二題可以直接得到
(1)Foo.getName();

由圖可知 全局Foo構(gòu)造函數(shù):Foo.getName = function() { alert(2); };

(2)getName();

全局getName函數(shù):getName = function() { alert(4); };

(3)Foo().getName();

Foo() 這樣調(diào)用那么就是把構(gòu)造函數(shù)當(dāng)做普通函數(shù)在調(diào)用
里面的this指向了window對(duì)象
所以里面return this,就相當(dāng)于把window對(duì)象返回了
res接收到的就是window對(duì)象
var res = Foo();
一定要注意,在Foo函數(shù)中,有一句代碼
getName = function(){ alert(1); };
這個(gè)代碼是給全局的getName重新賦值了一個(gè)function!
因此下面在調(diào)用的時(shí)候,這個(gè)全局的getName的alert結(jié)果已經(jīng)是1了
所以res.getName 其實(shí)就是在使用window.getName,其實(shí)就是直接在調(diào)用全局的getName函數(shù)!
        res.getName();
所以
Foo().getName() == window.getName() == function(){ alert(1); };

(4)getName();

由于上一步代碼已經(jīng)將 getName 值改變,所以
getName = function(){ alert(1); };

(5)new Foo.getName();

new 構(gòu)造函數(shù)();
下面的代碼就是把 Foo.getName整體當(dāng)做了一個(gè)構(gòu)造函數(shù)
1. 先new創(chuàng)建對(duì)象
2. 調(diào)用構(gòu)造函數(shù)  那么調(diào)用的就是Foo.getName 里面的alert語(yǔ)句就會(huì)被執(zhí)行
不需要關(guān)心這個(gè)語(yǔ)句最終創(chuàng)建出來(lái)的到底是個(gè)什么對(duì)象!
Foo.getName = function() { alert(2); };

(6)new Foo().getName();

上面的代碼可以拆解成
var obj = new Foo();
obj.getName();
由于obj中沒(méi)有g(shù)etName屬性,所以他將在原型Foo.prototype中查找
Foo.prototype.getName = function(){ alert(3); };

(7)new new Foo().getName();

上面的代碼可以拆解成
var obj = new Foo();
var func = obj.getName
同(6)題由于obj中沒(méi)有g(shù)etName屬性,所以他將在原型Foo.prototype中查找
Foo.prototype.getName = function(){ alert(3); };
所以
func = function(){ alert(3); };
所以
new func()輸出為 alert(3)

解題完畢,收工!

最后編輯于
?著作權(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)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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