返回

继承系列一 - JS 6 种常见的继承方式, 揭秘 JavaScript 的本质!

前端

JavaScript 继承是编程中的重要概念之一,它提供了创建新对象或类的方法,使新对象或类能够继承现有对象或类的属性和方法。在本文中,我们将探讨 6 种常见的 JavaScript 继承方式,包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承和字面量继承。通过深入了解这些继承方式,您将对 JavaScript 继承有更深入的理解,并能够在实际项目中灵活运用它们。

原型链继承

原型链继承是比较常见的继承方式之一,其中涉及的构造函数、原型和实例,三者之间存在着一定的关系,即每一个构造函数都有一个原型对象,原型对象又包含一个 proto 属性,该属性指向构造函数的原型对象。当我们创建一个实例时,该实例会继承构造函数的原型对象上的属性和方法。

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

Person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

const person = new Person("John");
person.sayHello(); // Output: Hello, my name is John

构造函数继承

构造函数继承也是一种常见的继承方式,它通过在子构造函数中调用父构造函数来实现继承。子构造函数会继承父构造函数的所有属性和方法,并可以在子构造函数中添加自己的属性和方法。

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

Person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

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

Student.prototype = Object.create(Person.prototype); // 继承父类原型
Student.prototype.constructor = Student; // 重写构造函数

const student = new Student("John", "Computer Science");
student.sayHello(); // Output: Hello, my name is John
console.log(student.major); // Output: Computer Science

组合继承

组合继承结合了原型链继承和构造函数继承的优点,它通过在子构造函数中调用父构造函数并同时设置子构造函数的原型对象为父构造函数的原型对象来实现继承。这样,子构造函数既继承了父构造函数的属性和方法,又继承了父构造函数原型对象上的属性和方法。

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

Person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

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

Student.prototype = Object.create(Person.prototype); // 继承父类原型
Student.prototype.constructor = Student; // 重写构造函数

const student = new Student("John", "Computer Science");
student.sayHello(); // Output: Hello, my name is John
console.log(student.major); // Output: Computer Science

原型式继承

原型式继承是一种通过直接复制对象来实现继承的方式。它通过创建一个新对象,并将其原型对象设置为要继承的对象来实现继承。这样,新对象就继承了要继承对象的属性和方法。

const person = {
  name: "John",
  sayHello: function() {
    console.log("Hello, my name is " + this.name);
  }
};

const student = Object.create(person); // 创建一个新对象,并将其原型对象设置为 person
student.major = "Computer Science"; // 添加自己的属性

student.sayHello(); // Output: Hello, my name is John
console.log(student.major); // Output: Computer Science

寄生式继承

寄生式继承是一种通过创建一个新对象,并将要继承的对象作为参数传入构造函数来实现继承的方式。在构造函数中,我们可以访问要继承对象的所有属性和方法,并将其复制到新对象中。

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

Person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

function Student(name, major) {
  const person = new Person(name); // 创建一个新对象,并将要继承的对象作为参数传入构造函数
  person.major = major; // 添加自己的属性
  return person; // 返回新对象
}

const student = new Student("John", "Computer Science");
student.sayHello(); // Output: Hello, my name is John
console.log(student.major); // Output: Computer Science

字面量继承

字面量继承是一种通过直接复制对象来实现继承的方式。它通过创建一个新的对象字面量,并将其值设置为要继承的对象的属性值来实现继承。这样,新对象就继承了要继承对象的属性和方法。

const person = {
  name: "John",
  sayHello: function() {
    console.log("Hello, my name is " + this.name);
  }
};

const student = {
  ...person, // 复制 person 对象的所有属性和方法
  major: "Computer Science" // 添加自己的属性
};

student.sayHello(); // Output: Hello, my name is John
console.log(student.major); // Output: Computer Science