__proto__是每个对象内部[[Prototype]]的可访问接口,作为原型链的“向上指针”,决定属性查找路径起点;它指向创建该对象的构造函数的prototype对象,构成从实例到Object.prototype再到null的委托链。

JavaScript 中 __proto__ 是对象内部 [[Prototype]] 的可访问接口,它直接决定属性查找的路径起点——不是装饰性字段,而是原型链运转的物理纽带。
__proto__ 是什么:每个对象的“向上指针”
它是一个对象自有属性(尽管早期非标准,现已被广泛支持),值为另一个对象或 null。它的存在让 JavaScript 引擎知道:“如果这个对象自己没有某个属性,该去哪找?”
- 所有普通对象(包括 {}、[]、new Date() 等)都自带 __proto__
- 函数对象也自带 __proto__(因为函数也是对象),同时还有自己的 prototype 属性
- __proto__ 不可枚举,不会被 for...in 遍历到,但可通过 Object.getOwnPropertyNames 查看
它如何连接原型链:从实例到终点的三步跳
当你写 obj.method(),引擎实际执行的是“顺着 __proto__ 一级级跳”的过程:
- 第一步:检查
obj自身是否有method(自有属性) - 第二步:没有?读取
obj.__proto__,在该对象上查找method - 第三步:还没找到?继续读
obj.__proto__.__proto__,重复直到遇到null
这条跳转路径就是原型链。例如:const arr = [] → arr.__proto__ === Array.prototype → Array.prototype.__proto__ === Object.prototype → Object.prototype.__proto__ === null。
立即学习“Java免费学习笔记(深入)”;
__proto__ 和 prototype 的关系:谁指向谁?
关键不在于名字像,而在于创建时的绑定规则:
-
function Fn() {}创建后,Fn.prototype是一个新对象(含 constructor 指回 Fn) -
const f = new Fn()时,引擎自动执行f.__proto__ = Fn.prototype - 所以
f.__proto__总是等于其构造函数的prototype,这是语言规范保证的
注意:Fn.__proto__ 指向 Function.prototype(因为函数也是 Function 的实例),而 Function.prototype.__proto__ 仍指向 Object.prototype —— 所有链最终收束于此。
为什么不能乱改 __proto__?
虽然技术上允许赋值(如 obj.__proto__ = otherObj),但会带来隐性成本:
- 现代 JS 引擎(V8 等)对原型链做大量优化,动态修改 __proto__ 可能触发去优化(deoptimization)
- 改变后,原链上已缓存的属性查找路径失效,影响性能
- 更推荐用
Object.setPrototypeOf(obj, proto)替代直接赋值,语义更清晰且可被静态分析
本质上,__proto__ 是原型链的“入口开关”,它把每个对象接入统一的委托系统——不复杂,但必须理解它才真正读懂 JS 的继承逻辑。


















