【前端面试题】面试专题之原型继承求值
大熊•
前言
前面文章详细介绍了 JS 中__proto__
和prototype
区别与关系,为了巩固加深相关理解,这里汇总了好多大厂的面试题。能够加深对知识的理解同时可以轻松通过面试。
题目
天花板的综合面试题
需要知道this
作用域, prototype
原型继承、new
运算符号的优先级。
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()
getName()
Foo().getName()
getName()
new Foo.getName()
new Foo().getName()
new new Foo().getName()
题目解析:
题目结果为:2、4、1、1、2、3、3
这是一道综合性题目,首先 getName
函数声明会先提升,然后 getName
函数表达式提升,但是因为函数声明提升在线,所以忽略函数表达式的提升,然后开始执行代码,执行到 var getName= ...
时,修改了 getName
的值,赋值成了打印 4
的新函数。
- 执行
Foo
函数的静态方法,打印出 2。 - 执行
getName
,当前getName
是打印出 4 的那个函数。 - 执行
Foo
函数,修改了全局变量getName
,赋值成了打印1
的函数,然后返回this
,因为是在全局环境下执行,所以this
指向window
,因为getName
已经被修改了,所以打印出 1。 - 因为
getName
没有被重新赋值,所以再执行仍然打印出 1。 new
操作符是用来调用函数的,所以new Foo.getName()
相当于new (Foo.getName)()
,所以new
的是Foo
的静态方法 getName,打印出2
。- 因为点运算符
(.)
的优先级和new
是一样高的,所以从左往右执行,相当于(new Foo()).getName()
,对Foo
使用new
调用会返回一个新创建的对象,然后执行该对象的getName
方法,该对象本身并没有该方法,所以会从Foo
的原型对象上查找,找到了,所以打印出3
。 - 和上题一样,点运算符
(.)
的优先级和new
一样高,另外new
是用来调用函数的,所以new new Foo().getName()
相当于new ((new Foo()).getName)()
,括号里面的就是上一题,所以最后找到的是Foo
原型上的方法,无论是直接调用,还是通过new
调用,都会执行该方法,所以打印出3
。