###變量提升綜合面試題
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)
解題完畢,收工!