【前端面试题】面试专题之原型继承求值

前言

前面文章详细介绍了 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 的新函数。

  1. 执行 Foo 函数的静态方法,打印出 2。
  2. 执行 getName,当前 getName 是打印出 4 的那个函数。
  3. 执行 Foo 函数,修改了全局变量 getName,赋值成了打印 1 的函数,然后返回 this,因为是在全局环境下执行,所以 this 指向 window,因为 getName 已经被修改了,所以打印出 1。
  4. 因为 getName 没有被重新赋值,所以再执行仍然打印出 1。
  5. new 操作符是用来调用函数的,所以 new Foo.getName()相当于 new (Foo.getName)(),所以 new 的是 Foo 的静态方法 getName,打印出 2。
  6. 因为点运算符(.)的优先级和 new 是一样高的,所以从左往右执行,相当于(new Foo()).getName(),对 Foo 使用 new 调用会返回一个新创建的对象,然后执行该对象的 getName 方法,该对象本身并没有该方法,所以会从 Foo 的原型对象上查找,找到了,所以打印出 3。
  7. 和上题一样,点运算符(.)的优先级和 new 一样高,另外 new 是用来调用函数的,所以 new new Foo().getName()相当于 new ((new Foo()).getName)(),括号里面的就是上一题,所以最后找到的是 Foo 原型上的方法,无论是直接调用,还是通过 new 调用,都会执行该方法,所以打印出 3。
关于我
loading