###变量提升综合面试题
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(); // ?
第一眼看到这个题目我是一脸蒙蔽,感觉无处下手~~(╯﹏╰)b,没办法啊,一步一步来,好在最后把这个东西给搞定了。下面来说说解题思路。
*解题步骤:
1.解变量提升题,如果第一眼不能快速得出答案,建议根据变量提升的原则分析出js变量提升后的代码
//变量提升后
//1.函数整体提升
function Foo() {
getName = function(){ alert(1); };
return this;
}
//2.同名函数和变量,函数提升,变量忽略声明
function getName(){ alert(5); }
//其他的不变
Foo.getName = function() { alert(2); };
Foo.prototype.getName = function(){ alert(3); };
getName = function() { alert(4); };
2.变量提升后,我们发现情况并不明朗,只能画个图了
全局Foo构造函数:Foo.getName = function() { alert(2); };
Foo原型:Foo.prototype.getName = function(){ alert(3); };
全局getName函数:getName = function() { alert(4); };(后赋值将前值覆盖)
3.开始解题
第一二题可以直接得到
(1)Foo.getName();
由图可知 全局Foo构造函数:Foo.getName = function() { alert(2); };
(2)getName();
全局getName函数:getName = function() { alert(4); };
(3)Foo().getName();
Foo() 这样调用那么就是把构造函数当做普通函数在调用
里面的this指向了window对象
所以里面return this,就相当于把window对象返回了
res接收到的就是window对象
var res = Foo();
一定要注意,在Foo函数中,有一句代码
getName = function(){ alert(1); };
这个代码是给全局的getName重新赋值了一个function!
因此下面在调用的时候,这个全局的getName的alert结果已经是1了
所以res.getName 其实就是在使用window.getName,其实就是直接在调用全局的getName函数!
res.getName();
所以
Foo().getName() == window.getName() == function(){ alert(1); };
(4)getName();
由于上一步代码已经将 getName 值改变,所以
getName = function(){ alert(1); };
(5)new Foo.getName();
new 构造函数();
下面的代码就是把 Foo.getName整体当做了一个构造函数
1. 先new创建对象
2. 调用构造函数 那么调用的就是Foo.getName 里面的alert语句就会被执行
不需要关心这个语句最终创建出来的到底是个什么对象!
Foo.getName = function() { alert(2); };
(6)new Foo().getName();
上面的代码可以拆解成
var obj = new Foo();
obj.getName();
由于obj中没有getName属性,所以他将在原型Foo.prototype中查找
Foo.prototype.getName = function(){ alert(3); };
(7)new new Foo().getName();
上面的代码可以拆解成
var obj = new Foo();
var func = obj.getName
同(6)题由于obj中没有getName属性,所以他将在原型Foo.prototype中查找
Foo.prototype.getName = function(){ alert(3); };
所以
func = function(){ alert(3); };
所以
new func()输出为 alert(3)
解题完毕,收工!