问题
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 的属性,原型链查找的顺序应该是
- a 自身
a.__proto__
相当于 A.prototypeA.prototype.__proto__
相当于 Object.prototypeObject.prototype.__proto__
这个为 null,原型链查找到头。
对于 function 定义的函数 A 的属性,原型链查找顺序应该是
- A 自身
A.__proto__
相当于 Function.prototypeFunction.prototype.__proto__
等于 Object.prototypeObject.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 的关系讲得很好,可以参考。