(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(); // ?  

第一眼看到这个题目我是一脸蒙蔽,感觉无处下手~~(╯﹏╰)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.变量提升后,我们发现情况并不明朗,只能画个图了

(BTMST)js变量提升面试题解析_第1张图片
Paste_Image.png
全局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)

解题完毕,收工!

你可能感兴趣的:((BTMST)js变量提升面试题解析)