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

前言

前面文章详细介绍了 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