JavaScript继承通过原型链实现,核心是建立__proto__隐式查找链以复用父类原型方法;需用Object.create(Super.prototype)而非直接赋值,避免共享原型,并手动修复constructor指向。

JavaScript 中的继承通过原型链实现,核心是让子类实例能访问父类原型上的方法,从而复用代码。关键不在“复制”方法,而在建立对象间的隐式查找链——当实例自身没有某个方法时,引擎自动沿 __proto__ 向上查找,直到找到或抵达 null。
构造函数 + 原型赋值:最基础的原型链继承
把父类原型对象整体赋给子类原型,子类实例就能通过原型链访问父类方法:
- 先定义父类构造函数,并在其
prototype上添加方法 - 子类构造函数不直接调用父类,而是用
Sub.prototype = Object.create(Super.prototype)建立原型链 - 手动修复
constructor指向,避免子类原型的constructor指向父类
例如:
function Animal(name) { this.name = name; }
Animal.prototype.say = function() { console.log(`I'm ${this.name}`); };
function Dog(name, breed) { Animal.call(this, name); this.breed = breed; }
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const d = new Dog('Leo', 'Golden');
d.say(); // 正常输出,方法来自 Animal.prototype
为什么不能直接写 Dog.prototype = Animal.prototype?
这样会让 Dog 和 Animal 共享同一个原型对象,修改 Dog.prototype 会意外影响 Animal 的行为。使用 Object.create() 创建的是一个新对象,其内部 [[Prototype]] 指向 Animal.prototype,既保持链路又隔离修改。
立即学习“Java免费学习笔记(深入)”;
继承后记得在子类原型上扩展自己的方法
子类专属逻辑应加在子类原型上,而不是覆盖父类原型。所有子类实例都能共享这些方法,且不影响父类:
- 可在
Object.create()后直接给Dog.prototype添加新方法 - 也可用对象字面量批量定义,但要注意保留
constructor - 若需重写父类方法(如 say),就在子类原型上重新定义同名方法,自然构成“覆盖”
注意实例属性和原型方法的分工
构造函数中用 this.xxx 初始化的属性属于实例,每次 new 都独立;而方法写在 prototype 上,被所有实例共享。这是复用的本质——方法只存一份,靠原型链统一访问,节省内存。


















