返回

深入浅出:理解 JavaScript 继承的本质

前端

原型链的奥秘

JavaScript 采用了一种独一无二的继承机制,即原型链(prototype chain)。它是一种动态的继承方式,允许对象继承自其他对象,从而实现代码复用和扩展。原型链的机制基于一个非常简单的概念:每个对象都有一个原型对象(prototype),而原型对象又可以有自己的原型对象,如此循环往复,形成一条链条,这就是原型链。

ES5 的继承方式

构造函数

ES5 中最常用的继承方式是使用构造函数(constructor)。构造函数是一种特殊的函数,当我们使用 new 调用它时,就会创建一个新的对象。这个新对象会继承自构造函数的原型对象,从而获得原型对象中的属性和方法。

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

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

const person1 = new Person('John');
person1.sayHello(); // Hello, my name is John

原型属性

除了使用构造函数,我们还可以在对象的原型对象上直接添加属性和方法。这种方式被称为原型属性(prototype property)。

Person.prototype.age = 20;

console.log(person1.age); // 20

ES6 的继承方式

Class

ES6 引入了 class 关键字,使 JavaScript 的继承方式更加接近其他面向对象语言。class 本质上是一种语法糖,它在幕后仍然是通过原型链实现继承的。

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

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

const person1 = new Person('John');
person1.sayHello(); // Hello, my name is John

extends

ES6 还引入了 extends 关键字,使我们可以直接在 class 中使用继承。

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

  study() {
    console.log(`I'm studying ${this.major}`);
  }
}

const student1 = new Student('Jane', 'Computer Science');
student1.sayHello(); // Hello, my name is Jane
student1.study(); // I'm studying Computer Science

总结

JavaScript 的继承机制是基于原型链的,ES5 和 ES6 都提供了不同的方式来实现继承。构造函数和原型属性是 ES5 中最常用的继承方式,而 class 和 extends 是 ES6 中引入的新语法,使 JavaScript 的继承方式更加清晰和简洁。