一个面试题关于函数的优先级

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

打印出来的结果是?2411233
但是我想的是 2514211.
有疑惑的地方

阅读 2.3k
2 个回答

挺有意思的一道题。

第一个 2 不用多解释,直接用的是 Foo.getName 静态方法。

第二个为啥是 4 呢?你会注意到最后有一个 var getName = funtion() {} 和一个 function getName,后声明的 function 咋没覆盖前面的 var 呢?因为 function 有函数提升,虽然是后声明的,反而会被提到当前作用域最前面去执行。(你可能会说 var 不也有变量提升吗?因为 JS 里函数是一等公民,函数提升比变量提升更优先!)

第三个和第四个为啥都是 1 呢?因为没 new 所以 Foo() 里的返回值 this 实际是 window,而 window.getName 上一步说了因为函数提升的原因,在执行 Foo() 之前其实是那个 var getName;但 Foo() 方法里给这个变量重新赋值了!

第五个是 2 也没啥讲的,虽然有 new 了,但 Foo 是引用而非调用,所以还是静态方法。

第六个第七个因为有 new 了、且调用了 Foo(),所以此时实际相当于实例化了一个 Foo 类型对象出来,那么后面的 .getName() 就是原型链方法了。


P.S. 最后两个连着的 new 可能容易迷惑,实际上的执行顺序是:

let a = new Foo();
let b = a.getName();
let c = new b;
新手上路,请多包涵

Js有变量提升、也有函数提升,但是赋值是不会提升的。
函数提升在变量提升前面,所以被覆盖

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题