手把手教你如何实现继承

手把手教你如何实现继承
最新回答
絮雨羽

2026-10-20 15:59:19

在 JavaScript 中实现继承有多种方式,下面我将从基础到高级逐步讲解,并提供代码示例和图示说明。

一、原型链继承(第一版)

核心思想:通过修改子类的原型指向父类实例来实现继承。

function Animal(name) { this.name = name;}Animal.prototype.eat = function() { console.log('eat');};function Cat(name) { Animal.call(this, name); // 继承父类属性}Cat.prototype = new Animal(); // 继承父类方法Cat.prototype.constructor = Cat; // 修正constructor// 测试const tom = new Cat('Tom');console.log(tom.name); // Tomtom.eat(); // eat

图示说明:

特点:

  • 实现了属性继承(通过call)
  • 实现了方法继承(通过原型链)
  • 缺点:父类构造函数被调用两次(new Animal()和Animal.call)
二、寄生组合式继承(优化版)

核心改进:使用空函数作为中介,避免重复调用父类构造函数。

function Animal(name) { this.name = name;}Animal.prototype.eat = function() { console.log('eat');};function Cat(name) { Animal.call(this, name); // 继承属性}// 关键优化点function inheritPrototype(child, parent) { function F() {} F.prototype = parent.prototype; child.prototype = new F(); child.prototype.constructor = child;}inheritPrototype(Cat, Animal);// 测试const jerry = new Cat('Jerry');console.log(jerry.name); // Jerryjerry.eat(); // eat

图示说明:

优点:

  • 只调用一次父类构造函数
  • 原型链保持干净
  • 良好的兼容性
三、ES6 Class 继承(推荐)

现代语法:使用extends和super关键字。

class Animal { constructor(name) { this.name = name; } eat() { console.log('eat'); }}class Cat extends Animal { constructor(name) { super(name); // 必须调用super }}// 测试const kitty = new Cat('Kitty');console.log(kitty.name); // Kittykitty.eat(); // eat

特点:

  • 语法更简洁
  • 自动处理原型链
  • 必须使用new调用
  • 支持静态方法继承
四、关键概念总结
  1. 属性继承:通过Parent.call(this)在子类构造函数中调用父类构造函数
  2. 方法继承:通过修改子类prototype指向父类原型
  3. constructor修正:继承后会改变constructor指向,需要手动修正
  4. 原型链检查:使用instanceof验证继承关系
五、完整实现示例// 父类function Animal(name, age) { this.name = name; this.age = age;}Animal.prototype.eat = function() { console.log(`${this.name} is eating`);};// 继承工具函数function extend(child, parent) { // 属性继承 child.prototype = Object.create(parent.prototype); child.prototype.constructor = child; // 保存父类引用 child.super = parent;}// 子类function Dog(name, age, breed) { Dog.super.call(this, name, age); // 调用父类构造函数 this.breed = breed;}extend(Dog, Animal);// 添加子类方法Dog.prototype.bark = function() { console.log('Woof!');};// 使用const max = new Dog('Max', 3, 'Labrador');max.eat(); // Max is eatingmax.bark(); // Woof!console.log(max instanceof Dog); // trueconsole.log(max instanceof Animal); // true六、最佳实践建议
  1. 现代项目优先使用ES6 Class语法
  2. 需要兼容旧环境时使用寄生组合式继承
  3. 避免直接操作__proto__(性能差且非标准)
  4. 注意边界情况:

    继承内置对象(如Array)的特殊处理

    静态属性和方法的继承

    new.target的使用

通过以上方法,你可以根据项目需求选择最适合的继承实现方式。ES6的class语法是最推荐的方式,它提供了最清晰直观的继承实现方式。