返回

JavaScript 继承 - 权威指南

前端

JavaScript 继承:揭开神秘面纱

JavaScript 继承是一个关键的概念,它使我们能够创建可重用的代码和扩展现有对象的功能。它允许我们从现有的对象(称为父对象)中创建新对象(称为子对象),并继承其属性和方法。

原型链继承

原型链继承是最基础的 JavaScript 继承方式。它利用每个对象都拥有一个内部属性 proto,指向其原型对象的事实。当我们访问子对象中的一个属性或方法时,JavaScript 会首先在子对象的 proto 中查找该属性或方法。如果没有找到,它会继续沿着原型链向上搜索,直到找到它或到达顶级原型对象(Object.prototype)。

代码示例:

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

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}`);
};

function Employee(name, jobTitle) {
  Person.call(this, name);  // 继承 Person 的属性和方法
  this.jobTitle = jobTitle;
}

const employee = new Employee("John", "Software Engineer");
employee.greet(); // 输出 "Hello, my name is John"

构造函数继承

构造函数继承通过在子构造函数中调用父构造函数来实现继承。这样,子构造函数可以访问和修改父构造函数中的属性和方法。

代码示例:

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

Animal.prototype.speak = function() {
  console.log(`I am a ${this.type}`);
};

function Dog(name, breed) {
  Animal.call(this, "Dog");  // 继承 Animal 的属性和方法
  this.name = name;
  this.breed = breed;
}

const dog = new Dog("Buddy", "Golden Retriever");
dog.speak(); // 输出 "I am a Dog"

类继承

ES6 引入了 class ,提供了更简洁和类似面向对象的语言的继承语法。类继承与构造函数继承类似,但是语法更加简洁。

代码示例:

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

  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

class Employee extends Person {
  constructor(name, jobTitle) {
    super(name);  // 继承 Person 的属性和方法
    this.jobTitle = jobTitle;
  }
}

const employee = new Employee("John", "Software Engineer");
employee.greet(); // 输出 "Hello, my name is John"

常见问题解答

  1. 原型链继承和构造函数继承有什么区别?

原型链继承通过 proto 链实现继承,而构造函数继承通过在子构造函数中调用父构造函数来实现继承。

  1. 为什么我们不使用 ES5 继承?

ES5 继承语法复杂、容易出错,并且不支持多重继承。ES6 类继承提供了更简洁、更健壮的替代方案。

  1. 什么是混合继承?

混合继承结合了原型链继承和构造函数继承的技术,以从多个父对象继承。

  1. 什么是组合继承?

组合继承使用委托而不是继承来实现类似继承的行为。子对象通过委派父对象的方法来获得父对象的功能。

  1. 何时使用继承?

当我们需要创建一个具有与其父对象相同或类似行为的新对象时,就使用继承。它促进了代码重用、减少了重复代码和提高了可维护性。