返回

JS 继承的七种姿势:纵横 JavaScript 继承之道

前端

  1. 原型链继承

原型链继承是 JavaScript 中最基本的继承方式。它是通过原型链来实现的。原型链是 JavaScript 中的一个概念,它了对象之间的继承关系。每个对象都有一个原型对象,原型对象又可能有自己的原型对象,如此往复,直到遇到 null。

function Person(name) {
  this.name = name;
}

Person.prototype.sayName = function() {
  console.log(this.name);
};

function Student(name, grade) {
  Person.call(this, name);
  this.grade = grade;
}

Student.prototype = Object.create(Person.prototype);

const student = new Student("John", 10);

student.sayName(); // John

在上面的代码中,Student 函数通过 Person.call(this, name) 调用 Person 函数的构造函数来继承 Person 函数的属性和方法。然后,Student.prototype 被设置为 Object.create(Person.prototype),这使得 Student 函数的原型对象成为 Person 函数的原型对象的副本。这样,Student 函数的实例就可以访问 Person 函数的属性和方法。

2. 类继承

ES6 中引入了 class ,它允许您使用类的方式来定义对象。类继承是通过 extends 关键字来实现的。

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

  sayName() {
    console.log(this.name);
  }
}

class Student extends Person {
  constructor(name, grade) {
    super(name);
    this.grade = grade;
  }
}

const student = new Student("John", 10);

student.sayName(); // John

在上面的代码中,Student 类通过 extends Person 继承了 Person 类的属性和方法。然后,Student 类的构造函数通过 super(name) 调用 Person 类的构造函数来继承 Person 类的属性和方法。这样,Student 类的实例就可以访问 Person 类的属性和方法。

3. 组合继承

组合继承是原型链继承和类继承的结合。它通过 Object.create()super() 关键字来实现。

function Person(name) {
  this.name = name;
}

Person.prototype.sayName = function() {
  console.log(this.name);
};

function Student(name, grade) {
  Person.call(this, name);
  this.grade = grade;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

const student = new Student("John", 10);

student.sayName(); // John

在上面的代码中,Student 函数通过 Person.call(this, name) 调用 Person 函数的构造函数来继承 Person 函数的属性和方法。然后,Student.prototype 被设置为 Object.create(Person.prototype),这使得 Student 函数的原型对象成为 Person 函数的原型对象的副本。最后,Student.prototype.constructor 被设置为 Student,这使得 Student 函数的实例的 constructor 属性指向 Student 函数。这样,Student 函数的实例就可以访问 Person 函数的属性和方法。

4. 寄生组合继承

寄生组合继承是组合继承的改进。它通过创建一个新的对象来继承 Person 函数的属性和方法,然后再将这个新的对象作为 Student 函数的原型对象。

function Person(name) {
  this.name = name;
}

Person.prototype.sayName = function() {
  console.log(this.name);
};

function Student(name, grade) {
  const person = new Person(name);
  person.grade = grade;
  return person;
}

const student = new Student("John", 10);

student.sayName(); // John

在上面的代码中,Student 函数通过创建一个新的 Person 对象来继承 Person 函数的属性和方法。然后,Student 函数将这个新的对象作为自己的原型对象。这样,Student 函数的实例就可以访问 Person 函数的属性和方法。

5. ES6 class 继承

ES6 中引入了 class 关键字,它允许您使用类的方式来定义对象。ES6 的类继承是通过 extends 关键字来实现的。

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

  sayName() {
    console.log(this.name);
  }
}

class Student extends Person {
  constructor(name, grade) {
    super(name);
    this.grade = grade;
  }
}

const student = new Student("John", 10);

student.sayName(); // John

在上面的代码中,Student 类通过 extends Person 继承了 Person 类的属性和方法。然后,Student 类的构造函数通过 super(name) 调用 Person 类的构造函数来继承 Person 类的属性和方法。这样,Student 类的实例就可以访问 Person 类的属性和方法。

6. Mixin

Mixin 是一个 JavaScript 对象,它包含了一组可以被其他对象复用的方法。Mixin 可以通过 Object.assign() 方法来实现。

const mixin = {
  sayName() {
    console.log(this.name);
  }
};

function Person(name) {
  this.name = name;
}

Object.assign(Person.prototype, mixin);

const person = new Person("John");

person.sayName(); // John

在上面的代码中,mixin 对象包含了一个 sayName() 方法。Person 函数通过 Object.assign(Person.prototype, mixin)mixin 对象的方法添加到 Person 函数的原型对象上。这样,Person 函数的实例就可以访问 mixin 对象的方法。

7. 多重继承

JavaScript 不支持多重继承,这意味着一个类只能继承一个父类。但是,您可以通过组合继承或寄生组合继承来实现多重继承。

function Person(name) {
  this.name = name;
}

Person.prototype.sayName = function() {
  console.log(this.name);
};

function Animal(type) {
  this.type = type;
}

Animal.prototype.sayType = function() {
  console.log(this.type);
};

function Student(name, grade) {
  Person.call(this, name);
  Animal.call(this, "Student");
  this.grade = grade;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

const student = new Student("John", 10);

student.sayName(); // John
student.sayType(); // Student

在上面的代码中,Student 函数通过组合继承继承了 Person 函数和 Animal 函数的属性和方法。这样,Student 函数的实例就可以访问 Person 函数和 Animal 函数的属性和方法。

总结

本文介绍了 JavaScript 中的七种继承方式。每种继承方式都有其优缺点,您可以根据自己的需求选择最合适的继承方式。