JavaScript原型链通过[[Prototype]]隐式链实现属性委托查找:先查自身,再沿链向上直至null;共享方法应定义在prototype上,引用类型属性须在构造函数中初始化以避免共享,子类继承后需手动修复constructor指向。

JavaScript 中原型链实现对象属性继承,靠的是属性查找机制:当访问一个对象的属性时,引擎先查对象自身;找不到,就顺着 [[Prototype]] 链向上查找,直到找到该属性,或到达链尾(null)为止。
属性查找走的是隐式原型链
每个对象内部都有一个 [[Prototype]](可通过 __proto__ 或 Object.getPrototypeOf() 访问),它指向自己的原型对象。这个链接不是复制属性,而是“委托访问”——相当于说:“我不懂这个属性,但我知道谁可能懂。”
- 普通对象(如
{})的[[Prototype]]默认指向Object.prototype - 构造函数实例(如
new Foo())的[[Prototype]]指向Foo.prototype -
Foo.prototype的[[Prototype]]通常指向Object.prototype,形成完整链条
继承属性的关键在于原型对象上定义
想让多个实例共享某个属性或方法,不能写在构造函数体内(否则每次新建都会重复创建),而要挂到构造函数的 prototype 上:
-
function Animal() { this.type = 'animal'; }→type是实例自有属性,不共享 -
Animal.prototype.eat = function() { console.log('eating'); };→eat是所有Animal实例共用的方法 - 子类通过设置
Child.prototype = Object.create(Parent.prototype),就能让子类实例在查不到自身属性时,继续查到父类原型上的eat
注意引用类型属性的陷阱
如果把数组、对象等引用类型直接写在父类原型上,所有子类实例会共享同一份数据,修改会影响彼此:
立即学习“Java免费学习笔记(深入)”;
- 错误示范:
Parent.prototype.colors = ['red'];→ 所有子实例共用这个数组 - 正确做法:在构造函数中初始化引用属性(保证每个实例独立),只把方法和不可变值放在原型上
- 若需共享状态,应明确设计为单例或使用 Symbol/WeakMap 等隔离手段
constructor 属性需要手动修复
用 Object.create(Parent.prototype) 设置子类原型后,Child.prototype.constructor 会指向 Parent,这不符合预期。需补一句:
Child.prototype.constructor = Child;
否则 new Child() 实例的 constructor 会误报为父类,影响 instanceof 判断和调试可读性。


















