面试:Function.prototype.a 请给出下列函数的执行输出

问题

Function.prototype.a = () => {
  console.log(1);
}
Object.prototype.b = () => {
  console.log(2);
}
function A() {}
const a = new A();
a.a();
a.b();
A.a()

笔者第一反应就懵逼,搞不懂特意放一个 Function.prototype.a 干什么,因为 function A 的原型链属性 prototype 只和 Object 有关系,和 Function 对象本身没啥关系。

面试中笔者猜测

a.a() // 会无法执行,因为 A 的原型的原型,我知道是 Object 而非 Function。
a.b() // 正常打印 2,因为 Object 的原型被加上了 b 方法,顺着原型链能被找得到。
A.a() // 第一反应和 a.a() 没有区别,因为顺着原型链还是只能找到 Object。但是面试官特意放上来这个,就让笔者疑神疑鬼的。

输出结果

最后面试完,特意去输出了下结果

a.a() // Uncaught TypeError: a.a is not a function



a.b() // 2
A.a() // 1
A.b() // 2

也就是说 A 可以找到 Function.prototype 和 Object.prototype 的属性。而 a 只能找到 Object.prototype 的。

嗯,这个 A 挺让人困惑的。

A instanceof Object // true
A instanceof Function // true

a instanceof A // true
a instanceof Object // true
a instanceof Function // false

分析

对于 new 出来的对象 a 的属性,原型链查找的顺序应该是

  1. a 自身
  2. a.__proto__ 相当于 A.prototype
  3. A.prototype.__proto__ 相当于 Object.prototype
  4. Object.prototype.__proto__ 这个为 null,原型链查找到头。

对于 function 定义的函数 A 的属性,原型链查找顺序应该是

  1. A 自身
  2. A.__proto__ 相当于 Function.prototype
  3. Function.prototype.__proto__ 等于 Object.prototype
  4. Object.prototype.__proto__ 这个为 null,原型链查找到头。

总之几点原则:

  • 所有构造函数的的 prototype 方法的 __proto__ 都指向 Object.prototype (除了 Object.prototype 自身)
  • Object 是 Function 的实例对象, Object.__proto__ === Function.prototype // true
  • Function.prototype 是 Object 的实例对象。Function.prototype.__proto__ === Object.prototype // true

参考

这篇对 Object 和 Function 的关系讲得很好,可以参考。

js 原型的问题 Object 和 Function 到底是什么关系?

posted @ 2020-05-21 14:15  Ever-Lose  阅读(1737)  评论(1编辑  收藏  举报