__proto__ 是对象的“向上找路标”,指向其构造函数的 prototype,逐级追溯形成原型链,终点为 Object.prototype.__proto__ === null。
直接用 __proto__ 查看对象的原型指向,是理解原型链“物理路径”最直观的方式——它把抽象的继承关系变成一条可逐层追踪的指针链。
__proto__ 是对象身上的“向上找路标”
每个普通对象(除 null)都有一个内部属性 [[Prototype]],浏览器通过非标准但广泛支持的 __proto__ 暴露出来。它不是用来赋值或修改的,而是用来观察“这个对象的父级原型是谁”:
-
const obj = {};→obj.__proto__ === Object.prototype -
const arr = [];→arr.__proto__ === Array.prototype -
function Fn() {}→(new Fn()).__proto__ === Fn.prototype
顺着 __proto__ 一级级往上走,就是原型链的物理路径
原型链不是概念推演,而是一连串真实的 __proto__ 指向:
- 实例对象的
__proto__→ 构造函数的prototype - 构造函数的
prototype本身也是对象 → 它的__proto__指向Object.prototype -
Object.prototype.__proto__→null(链的终点)
例如:const date = new Date();date.__proto__ === Date.prototypeDate.prototype.__proto__ === Object.prototypeObject.prototype.__proto__ === null
这就是一条三跳落地的物理链。
注意函数对象的双重身份:既是函数,又是对象
函数比较特殊,它既是可调用的对象,又自带 prototype 属性:
-
function F() {}是Function的实例 →F.__proto__ === Function.prototype -
Function本身也是函数 →Function.__proto__ === Function.prototype -
Function.prototype是个普通对象 →Function.prototype.__proto__ === Object.prototype
所以函数的 __proto__ 和它的 prototype 指向完全不同,不能混淆。
用 console.dir 辅助验证指向关系
在浏览器控制台执行 console.dir(obj),展开对象能看到 [[Prototype]] 字段,点开就能看到它实际指向哪个原型对象。再点开那个原型对象的 [[Prototype]],继续向下……这种“点击式溯源”比纯代码更直观地呈现原型链的物理结构。










