JavaScript原型链多级继承本质是子类prototype指向父类实例,形成逐层查找链;需用new Parent()赋值并修复constructor,方法须挂prototype避免重复创建,警惕引用类型属性共享。

JavaScript 中原型链实现多层级继承,本质是让子类的 prototype 指向父类的一个实例,从而形成“实例 → 子类原型 → 父类原型 → Object.prototype → null”这条可逐层向上查找的链路。关键不在写多少层,而在于每层都正确建立原型连接并修复构造器指向。
用 new 父类() 设置子类 prototype
这是构建多级原型链的第一步。不能直接赋值 Child.prototype = Parent.prototype,那样会共享引用、丢失自有属性初始化逻辑;必须用 new Parent() 创建一个干净的父类实例,作为子类的原型基础。
-
Dog.prototype = new Animal();—— Dog 实例能访问 Animal 原型上的eat和sleep -
Bulldog.prototype = new Dog();—— Bulldog 实例不仅能访问自己的snore,还能沿链找到bark、eat、toString - 注意:每次用
new Parent()赋值后,constructor会变成Parent,需手动重设
逐层修复 constructor 指向
因为 Child.prototype = new Parent() 后,Child.prototype.constructor 指向的是 Parent,不是 Child。这会影响 instanceof 判断和代码可读性,必须显式修正。
Dog.prototype.constructor = Dog;Bulldog.prototype.constructor = Bulldog;- 也可在设置 prototype 后用
Object.defineProperty配置writable: false,更严谨
区分自有属性与共享方法的存放位置
构造函数负责初始化每个实例独有的数据(如 this.name),所有复用的方法必须统一挂到 Constructor.prototype 上。否则,方法会被重复创建,失去原型继承的意义。
立即学习“Java免费学习笔记(深入)”;
- 错误做法:
function Dog() { this.bark = function() {...} }—— 每个 Dog 实例都有独立 bark 函数 - 正确做法:
Dog.prototype.bark = function() {...}—— 所有 Dog 实例共享 bark 方法 - Animal/Dog/Bulldog 各自的原型上只放本层新增方法,共用逻辑靠链式查找自动获得
警惕引用类型属性的共享陷阱
如果父类构造函数中给 this 赋了引用类型(如数组、对象),它会成为所有子类实例共享的“公共区域”,修改一处会影响全部。
- 例如:
function Animal() { this.skills = []; },则所有 Dog 实例共用同一个skills数组 - 解决办法:在子类构造函数中重新初始化该属性,或改用原型方法操作私有数据
- 这不是原型链本身的问题,而是构造函数执行时机导致的数据归属混淆


















