JavaScript继承:原生原型链机制及Function与Object原型疑问
这是个非常经典的原型链绕弯问题,很多刚深挖JS原型机制的同学都会卡在这里,咱们一步步把它捋清楚:
先明确几个核心前提
- 所有普通对象的原型链最终都会指向
Object.prototype,再到null - 所有函数对象(包括构造函数、普通函数)的
__proto__默认指向Function.prototype——除了一个特例:Function本身
为什么第四个结果Function.__proto__ === Object.prototype是false?
这是因为Function是JavaScript里唯一一个「自身就是自身构造函数」的特殊存在:
console.log(Function.__proto__ === Function.prototype); // true!
你没看错,Function的原型(__proto__)指向的是它自己的prototype对象,而不是Object.prototype,所以你的第四个alert结果自然是false。
但这并不意味着Function脱离了Object的原型链——因为Function.prototype的原型依然指向Object.prototype:
console.log(Function.prototype.__proto__ === Object.prototype); // true
所以Function的完整原型链是:Function → Function.prototype → Object.prototype → null,最终还是归到了Object.prototype,这也符合「所有内容最终继承自Object」的大逻辑。
为什么Object.getPrototypeOf(Function) === Object.getPrototypeOf(Object)是true?
首先要记住:Object本身也是一个函数(它是用来创建对象的构造函数),而所有函数(包括Function自己)都是Function的实例,所以:
console.log(Object.__proto__ === Function.prototype); // true
而我们刚才已经知道Function.__proto__ === Function.prototype,所以Object.getPrototypeOf(Function)获取的是Function.__proto__(也就是Function.prototype),Object.getPrototypeOf(Object)获取的是Object.__proto__(也是Function.prototype),两者自然相等,结果为true。
再把你的例子里的原型链完整梳理一遍,帮你彻底理清:
obj的原型链:obj → Rabbit.prototype → Object.prototype → nullRabbit的原型链:Rabbit → Function.prototype → Object.prototype → nullFunction的原型链:Function → Function.prototype → Object.prototype → nullObject的原型链:Object → Function.prototype → Object.prototype → null
这样看下来,所有对象最终都继承自Object.prototype,只是Function和Object作为顶层构造函数,在原型链的顶端有这个特殊的循环指向而已。
内容的提问来源于stack exchange,提问作者D_S_X

