JavaScript中__proto__与Prototype的混淆:为何Person.__proto__≠Object.prototype?
搞懂JavaScript原型链:为什么Person.__proto__不等于Object.prototype?
别慌!你没遗漏什么,只是混淆了函数对象和普通实例对象的原型链路径而已,咱们一步步拆解开看。
先回顾你的代码:
function Person(name) { this.name = name; } var eve = new Person("Eve");
首先看实例eve的原型链(你已经搞懂的部分)
eve是Person的实例,所以它的原型__proto__直接指向构造函数的prototype属性:console.log(eve.__proto__ === Person.prototype); // truePerson.prototype本质是一个普通对象(默认情况下),普通对象的原型都是Object.prototype,所以:
这部分你理解的完全没问题。console.log(eve.__proto__.__proto__ === Object.prototype); // true
重点:Person作为函数,它的原型链不一样!
在JavaScript里,所有函数本身都是Function构造函数的实例——没错,包括你自己定义的Person,甚至内置的Object、Array这些构造函数都是!
所以Person的__proto__指向的是Function.prototype,而不是直接指向Object.prototype:
console.log(Person.__proto__ === Function.prototype); // true
那Function.prototype的原型呢?它本身是一个特殊的对象(注意不是函数),所以它的__proto__才指向Object.prototype:
console.log(Function.prototype.__proto__ === Object.prototype); // true
所以Person的完整原型链是:Person → Function.prototype → Object.prototype → null
为什么说“所有对象都继承自Object”仍然成立?
因为不管是普通实例对象(比如eve)还是函数对象(比如Person),最终的原型链终点都是Object.prototype,只是函数对象多了一层Function.prototype的中间环节而已。
举个更直观的“族谱”例子:
eve的直系长辈:Person.prototype→Object.prototypePerson的直系长辈:Function.prototype→Object.prototype- 所有人最终的“老祖宗”都是
Object.prototype,再往上就是null(没有原型了)
再验证几个关键点加深理解
// 内置构造函数Object也是Function的实例 console.log(Object.__proto__ === Function.prototype); // true // Function的__proto__指向自己的prototype?有点特殊,但不影响整体逻辑 console.log(Function.__proto__ === Function.prototype); // true // 所有对象最终都能追溯到Object.prototype console.log(Person instanceof Object); // true console.log(eve instanceof Object); // true
内容的提问来源于stack exchange,提问作者StrugglingCoder
相关产品推荐
相关产品推荐

