跳到主要内容

面试题1

· 阅读需 2 分钟

题目

function Foo() {
getName = function () {
console.log(1);
};
return this;
}
Foo.getName = function () {
console.log(2);
};
Foo.prototype.getName = function () {
console.log(3);
};
var getName = function () {
console.log(4);
};
function getName() {
console.log(5);
}
Foo.getName(); // 2
Foo().getName(); // 1
getName(); // 1
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3

上面是字节的一道面试题,涉及到的考点很多,原型,变量提升,函数提升,this的指向,new的原理,new xx(...) vs new xx vs . 的运算优先级,是一道相当综合的面试题

解析

1、 Foo.getName();

调用Foo的静态方法,所以,打印2

2、 Foo().getName();

Foo()就是普通函数调用,返回的this是window,后面调用window.getName()
而window下的getName在Foo()中调用getName被重新赋值,所以,打印1

3、 getName();

在执行过Foo().getName()的基础上,所以getName=function(){console.log(1)},所以,打印1,[如果getName()放在Foo().getName()上执行打印结果为4]

4、 new Foo.getName();

构造器私有属性的getName(),所以,打印2

5、 new Foo().getName();

原型上的getName(),打印3

6、 new new Foo().getName()

首先new Foo()得到一个空对象{}, 这个空对象的proto指向了Foo.prototype

第二步 Foo.prototype在上面的代码中已经挂上了打印3的一个函数

第三步 new new Foo().getName() = new {}.getName() = new ({}.proto.getName)() = new (Foo.prototype.getName)() = new (function () {console.log(3);})()

第四步 经过第三步的分析,就可以得出结果,打印3