返回

从零秒速通面向对象编程:揭秘JS继承之谜

前端

面向对象编程(OOP)是一种强大的编程范式,可以帮助我们构建更复杂、更可维护的应用程序。在OOP中,我们可以创建对象来表示现实世界中的实体,并通过继承来复用代码和数据。

JavaScript也是一门支持面向对象编程的语言,但它与其他语言(如Java和C++)的实现方式略有不同。在JavaScript中,继承是通过原型链来实现的。

原型链是一个对象到另一个对象的连接列表,它允许对象访问另一个对象的所有属性和方法。当我们创建新对象时,它会自动继承其父对象的原型链,从而获得父对象的所有属性和方法。

1. 构造函数

构造函数是创建新对象的一种方法。当我们使用new运算符调用构造函数时,它会创建一个新的对象并将其分配给一个变量。

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

const person = new Person('John', 30);

console.log(person.name); // John
console.log(person.age); // 30

2. 原型链

每个对象都有一个原型链,它指向另一个对象。这个对象可能是另一个构造函数,也可能是null。

当我们访问一个对象的属性或方法时,JavaScript会首先在该对象中查找。如果找不到,它会沿着原型链向上查找,直到找到该属性或方法。

const person = new Person('John', 30);

person.sayHello(); // TypeError: person.sayHello is not a function

在上面的例子中,我们试图调用person对象的sayHello()方法,但它不存在。JavaScript会沿着原型链向上查找,直到找到Person构造函数。Person构造函数有一个sayHello()方法,所以JavaScript会调用它。

3. 原型继承

原型继承是JavaScript中实现继承的一种方式。当我们创建新对象时,它会自动继承其父对象的原型链,从而获得父对象的所有属性和方法。

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

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const person = new Person('John', 30);

person.sayHello(); // Hello, my name is John and I am 30 years old.

4. 函数式继承

函数式继承是JavaScript中实现继承的另一种方式。这种方式使用了一个函数来创建新对象,该函数将父对象作为参数。

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

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

const student = new Student('John', 30, 'Computer Science');

console.log(student.name); // John
console.log(student.age); // 30
console.log(student.major); // Computer Science

5. 组合继承

组合继承是函数式继承和原型继承的结合。这种方式使用了一个函数来创建新对象,该函数将父对象作为参数。然后,它使用Object.create()方法来创建新对象的原型,该原型继承了父对象的原型。

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

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

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

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

const student = new Student('John', 30, 'Computer Science');

console.log(student.name); // John
console.log(student.age); // 30
console.log(student.major); // Computer Science
student.sayHello(); // Hello, my name is John and I am 30 years old.

6. ES6 Class

ES6 Class是JavaScript中实现继承的一种新的方式。它使用class来定义类,并使用extends关键字来继承类。

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

  sayHello() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

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

const student = new Student('John', 30, 'Computer Science');

console.log(student.name); // John
console.log(student.age); // 30
console.log(student.major); // Computer Science
student.sayHello(); // Hello, my name is John and I am 30 years old.

总结

JavaScript中有多种实现继承的方式,每种方式都有其优缺点。在实际开发中,我们应该根据具体情况选择合适的继承方式。