返回

技术指南:掌握JS高级之图解ES6之前的6种继承方式

前端

导言

继承是面向对象编程(OOP)的一项基本原则,允许一个类(子类)获取另一个类(父类)的特征和行为。ES6引入extends简化了继承的写法,但在此之前,JavaScript中有许多不同的继承方式,以下我们将一一介绍。

1. 构造函数继承

构造函数继承是最基本也是最容易理解的继承方式。子类通过调用父类的构造函数来继承父类的属性和方法。

// 父类
function Person(name) {
  this.name = name;
}

// 子类
function Student(name, major) {
  // 调用父类的构造函数
  Person.call(this, name);
  this.major = major;
}

2. 原型继承

原型继承是另一种简单但有效的继承方式。子类通过继承父类的原型对象来继承父类的属性和方法。

// 父类
function Person() {}
Person.prototype.name = "John Doe";

// 子类
function Student() {}
Student.prototype = new Person();
Student.prototype.major = "Computer Science";

3. 组合继承

组合继承结合了构造函数继承和原型继承的优点,既能继承父类的属性和方法,又能通过super关键字访问父类的方法。

// 父类
function Person(name) {
  this.name = name;
}

// 子类
function Student(name, major) {
  // 调用父类的构造函数
  Person.call(this, name);
  this.major = major;
}

// 将父类的原型对象赋值给子类的原型对象
Student.prototype = Object.create(Person.prototype);

// 重写子类的构造函数
Student.prototype.constructor = Student;

4. 寄生继承

寄生继承是一种不通过原型链继承的继承方式。子类通过创建一个新对象,并将父类的方法复制到新对象上,从而实现继承。

// 父类
function Person(name) {
  this.name = name;
}

// 子类
function Student(name, major) {
  // 创建一个新对象
  const student = Object.create({});

  // 将父类的方法复制到新对象上
  Object.assign(student, Person.prototype);

  // 为新对象添加自己的属性和方法
  student.name = name;
  student.major = major;

  // 返回新对象
  return student;
}

5. 寄生组合继承

寄生组合继承结合了寄生继承和组合继承的优点,既能继承父类的属性和方法,又能通过super关键字访问父类的方法。

// 父类
function Person(name) {
  this.name = name;
}

// 子类
function Student(name, major) {
  // 创建一个新对象
  const student = Object.create({});

  // 将父类的方法复制到新对象上
  Object.assign(student, Person.prototype);

  // 为新对象添加自己的属性和方法
  student.name = name;
  student.major = major;

  // 调用父类的构造函数
  Person.call(student, name);

  // 返回新对象
  return student;
}

6. ES6类继承

ES6引入extends关键字,简化了继承的写法,也消除了各种继承方式之间的差异。

// 父类
class Person {
  constructor(name) {
    this.name = name;
  }
}

// 子类
class Student extends Person {
  constructor(name, major) {
    super(name);
    this.major = major;
  }
}

结论

在ES6之前,JavaScript中的继承方式多种多样,各有优缺点。ES6的引入简化了继承的写法,也消除了各种继承方式之间的差异,使得继承更加清晰和直观。