javascript继承基于原型链委托而非类复制,对象通过[[prototype]]链接到原型,查找属性时沿链向上直到object.prototype(其[[prototype]]为null),赋值则始终作用于自身。

JavaScript 的继承模型不是靠“类”一层层复制出来的,而是靠对象之间建立委托关系——一个对象找不到某个属性时,会自动把请求“转交”给它的原型对象,原型再不行就继续往上交,直到无处可交为止。这种委托链条就是原型链,它构成了 JS 继承的实质。
原型继承的核心是委托,不是拷贝
每个函数都有 prototype 属性,它是一个普通对象,专为将来用 new 创建的实例服务;而每个实例对象都有内部属性 [[Prototype]](可通过 __proto__ 或 Object.getPrototypeOf() 访问),它指向构造函数的 prototype 对象。
关键点在于:实例并不拥有原型上的方法,只是能“顺着链子”去调用——这叫行为委托,不是属性复制。
- 函数有
prototype,普通对象没有 - 所有对象(除
null)都有[[Prototype]],即隐式原型 -
Child.prototype = new Parent()这类写法,本质是让子类原型“链接到”父类实例,从而获得其原型链上的能力
链式查找是怎么发生的?
当你写 obj.method(),JS 引擎按固定顺序逐层查找:
- 先查
obj自身有没有method - 没有就查
obj.__proto__(即它的直接原型) - 还没就查
obj.__proto__.__proto__(即原型的原型) - 一直查到
Object.prototype,它的__proto__是null,链在此终止
如果整条链都找不到,结果就是 undefined。比如 {}.hasOwnProperty 能用,是因为它在 Object.prototype 上;{}.toString 同理——这些通用方法都挂在这条链的高处。
为什么原型链终点一定是 Object.prototype?
几乎所有通过字面量或 new 创建的对象,其原型链最终都会连到 Object.prototype。这是因为:
-
{}等价于new Object(),所以{}.__proto__ === Object.prototype -
function F(){}的F.prototype.__proto__也等于Object.prototype -
Object.prototype.__proto__是null,这是规范规定的链尾
这个统一终点保证了基础方法(如 toString、valueOf、hasOwnProperty)对绝大多数对象可用。
实际中容易忽略的关键细节
原型链查找只发生在读取属性时,赋值或删除会作用在当前对象本身:
-
obj.x = 123总是在obj上新建或覆盖x,不会影响原型 -
'x' in obj会沿链查找,但obj.hasOwnProperty('x')只看自身 - 修改
Parent.prototype会影响所有已创建和将创建的子实例——这是动态性的体现,也是潜在风险点
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











