返回

JS中实现继承的多种方式

前端

前言

在面向对象编程中,继承是允许一个类从另一个类继承属性和方法的一种机制。继承使代码复用成为可能,并允许开发者创建更复杂的对象。

原型链继承

原型链继承是JavaScript中实现继承的最基本的方式。原型链是指一个对象到其原型对象的链接。原型对象也是一个对象,它拥有自己的属性和方法。当一个对象访问一个不存在于自身属性中的属性或方法时,它会沿原型链向上查找,直到找到该属性或方法。

原型链继承的实现方式非常简单,只需要将子类的原型对象设置为父类的实例对象即可。如下所示:

function Parent() {
  this.name = "父类";
}

function Child() {
  this.age = 18;
}

Child.prototype = new Parent();

const child = new Child();

console.log(child.name); // "父类"
console.log(child.age); // 18

原型链继承的优点在于简单易懂,并且开销较小。缺点在于,子类无法访问父类的私有属性和方法,并且子类的原型对象与父类的实例对象共享,这可能会导致意外的修改。

构造函数继承

构造函数继承是另一种实现继承的方式,它通过在子类的构造函数中调用父类的构造函数来实现。如下所示:

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

function Child(name, age) {
  Parent.call(this, name);
  this.age = age;
}

const child = new Child("小明", 18);

console.log(child.name); // "小明"
console.log(child.age); // 18

构造函数继承的优点在于,子类可以访问父类的私有属性和方法,并且子类的原型对象与父类的实例对象是独立的。缺点在于,构造函数继承的实现方式较为复杂,并且开销较大。

组合继承

组合继承是原型链继承和构造函数继承的结合体。它通过在子类的原型对象中设置父类的实例对象,同时在子类的构造函数中调用父类的构造函数来实现。如下所示:

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

function Child(name, age) {
  Parent.call(this, name);
  this.age = age;
}

Child.prototype = new Parent();

const child = new Child("小明", 18);

console.log(child.name); // "小明"
console.log(child.age); // 18

组合继承的优点在于,它结合了原型链继承和构造函数继承的优点,既可以访问父类的私有属性和方法,又可以保持子类的原型对象与父类的实例对象独立。缺点在于,组合继承的实现方式较为复杂,并且开销较大。

原型式继承

原型式继承是通过创建一个新的对象,并将其原型对象设置为另一个对象来实现继承。如下所示:

const parent = {
  name: "父类",
};

const child = Object.create(parent);
child.age = 18;

console.log(child.name); // "父类"
console.log(child.age); // 18

原型式继承的优点在于,它非常简单易懂,并且开销较小。缺点在于,子类无法访问父类的私有属性和方法,并且子类的原型对象与父类的实例对象共享,这可能会导致意外的修改。

寄生式继承

寄生式继承是通过创建一个新的对象,并将其原型对象设置为另一个对象的副本,然后再向新对象添加自己的属性和方法来实现继承。如下所示:

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

function Child(name, age) {
  const parent = new Parent(name);
  parent.age = age;
  return parent;
}

const child = new Child("小明", 18);

console.log(child.name); // "小明"
console.log(child.age); // 18

寄生式继承的优点在于,它可以访问父类的私有属性和方法,并且子类的原型对象与父类的实例对象是独立的。缺点在于,寄生式继承的实现方式较为复杂,并且开销较大。

类式继承

ES6中引入了class,它使JavaScript中的继承语法更加类似于其他面向对象语言。类式继承的实现方式如下:

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

class Child extends Parent {
  constructor(name, age) {
    super(name);
    this.age = age;
  }
}

const child = new Child("小明", 18);

console.log(child.name); // "小明"
console.log(child.age); // 18

类式继承的优点在于,它非常简单易懂,并且开销较小。缺点在于,类式继承只支持单继承,并且不支持多态。

总结

JavaScript中实现继承的方式有很多种,每种方式都有其优缺点。开发者可以根据具体情况选择最合适的方式。

参考资料