javascript原型继承中,显式原型prototype仅属函数,用于new时赋给实例的__proto__;所有对象都有__proto__指向其构造函数的prototype;属性查找沿__proto__链逐级向上直至null。

要理清 JavaScript 原型继承中隐式原型与显式原型的寻址流转,关键不是背概念,而是看清“谁指向谁”“查属性时往哪走”“链怎么断”。下面从三个核心环节讲清楚整个流转过程。
显式原型(prototype)是谁的?只属于函数
只有函数对象才有 prototype 属性,它是一个普通对象,默认自带 constructor 指回自身。这个属性本身不参与运行时查找,只在构造实例时被“复制”过去。
- 普通调用函数(如
Person())时,prototype完全没用 - 当用
new Person()创建实例时,引擎会把该实例的隐式原型设为Person.prototype -
class本质也是函数,所以MyClass.prototype同样存在且起作用
隐式原型(__proto__)是谁的?每个对象都有
所有对象(包括数组、函数、字面量对象)都内置一个 [[Prototype]] 内部槽,JavaScript 提供 __proto__(非标准但广泛支持)或更推荐的 Object.getPrototypeOf() 来访问它。
- 函数对象也有
__proto__,它指向Function.prototype(因为函数是Function构造出来的) - 普通对象(如
{}或Object.create(null))的__proto__指向Object.prototype,除非显式切断 - 实例对象的
__proto__总等于其构造函数的prototype,例如obj.__proto__ === ObjConstructor.prototype
属性查找时的完整流转路径
当你写 obj.method() 或 obj.prop,JS 引擎按以下顺序逐层向上找:
- 先查
obj自身是否拥有该属性(自有属性,hasOwnProperty可判) - 没有就查
obj.__proto__(即构造函数的prototype) - 还没找到,就继续查
obj.__proto__.__proto__(通常是Object.prototype) - 再往上是
Object.prototype.__proto__,值为null,查找终止
这条“__proto__ → prototype → __proto__ → ... → null”的链条,就是原型链。所有继承、方法复用、instanceof 判断都依赖它。
常见易混点直击
这几个关系必须分清,否则流转就乱了:
-
Fn.prototype !== Fn.__proto__:前者是Fn作为构造函数时给实例用的;后者是Fn自己作为对象,由Function构造而来 -
obj.constructor不一定等于构造函数:它只是obj.__proto__.constructor的引用,可被覆盖或丢失 -
Object.create(null)创建的对象没有__proto__链,toString等方法直接不可用 - 箭头函数没有
prototype,不能用new,所以也没有实例的隐式原型承接问题
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











