返回

深层次剖析JS中的继承与原型链

前端

在JavaScript中,继承是对象获得另一个对象的属性和方法的过程,而原型链则是实现继承的一种机制。

1. 对象、函数和原型

在JavaScript中,一切皆对象。函数也是对象,它拥有自己的属性和方法。每个对象都有一个原型,原型也是一个对象,它包含了该对象的所有共有属性和方法。对象的原型可以通过__proto__属性访问。

const obj = {};
console.log(obj.__proto__); // Object {}

输出结果为Object {},表示obj的原型是Object的实例。

2. 原型链

原型链是一个对象到其原型的映射关系。当访问一个对象的属性或方法时,如果该对象本身不具备该属性或方法,那么JavaScript引擎会沿着原型链向上查找,直到找到该属性或方法。

const obj = {
  name: 'John Doe'
};

obj.age = 30; // 添加一个属性

console.log(obj.age); // 30

delete obj.age; // 删除一个属性

console.log(obj.age); // undefined

console.log(obj.__proto__.age); // undefined

输出结果为undefined,表明obj对象本身没有age属性,JavaScript引擎沿着原型链向上查找,直到Object原型,也没有找到age属性,因此返回undefined

3. 继承

JavaScript中的继承是通过原型链实现的。当一个对象被创建时,它会获得其原型对象的所有属性和方法。这使得我们可以通过创建一个新对象并将其原型设置为另一个对象来实现继承。

const parentObj = {
  name: 'John Doe'
};

const childObj = Object.create(parentObj);

console.log(childObj.name); // John Doe

childObj.age = 30;

console.log(childObj.age); // 30

console.log(childObj.__proto__); // { name: 'John Doe' }

输出结果为John Doe30,表明childObj对象继承了parentObj对象的name属性和age属性。

4. ES6 class

ES6中引入了class,它提供了一种更简洁的方式来定义类和实现继承。

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

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

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

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

const john = new Student('John Doe', 'Computer Science');

john.greet(); // Hello, my name is John Doe
john.study(); // I'm studying Computer Science

输出结果为Hello, my name is John DoeI'm studying Computer Science,表明john对象继承了Person类的name属性和greet()方法,并拥有自己的major属性和study()方法。

5. 总结

JavaScript中的继承是通过原型链实现的。ES6中引入了class关键字,它提供了一种更简洁的方式来定义类和实现继承。