返回

丰富多彩的JS继承方式探索之旅

前端

在软件开发领域,继承是一种强大的工具,它允许新类共享父类的属性和方法,从而实现代码的重用和维护性。JavaScript作为一门强大的脚本语言,也提供了多种继承方式,让开发者能够灵活构建复杂的应用。

原型链继承

原型链继承是JavaScript中最为基本的一种继承方式。在这种方式下,子类继承父类的原型对象,从而拥有父类的属性和方法。这种继承方式非常简单易懂,而且能够实现多重继承。

优点:

  • 实现简单,易于理解和使用。
  • 支持多重继承。

缺点:

  • 无法访问父类的构造函数。
  • 无法修改父类的属性和方法。

示例:

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

Parent.prototype.sayHello = function() {
  console.log('父类说你好');
};

function Child() {
  this.name = '子类';
}

Child.prototype = new Parent();

const child = new Child();

console.log(child.name); // 子类
child.sayHello(); // 父类说你好

借助构造函数继承

借助构造函数继承是另一种在JavaScript中常用的继承方式。在这种方式下,子类通过调用父类的构造函数来继承父类的属性和方法。这种继承方式能够访问父类的构造函数,并且能够修改父类的属性和方法。

优点:

  • 能够访问父类的构造函数。
  • 能够修改父类的属性和方法。

缺点:

  • 无法实现多重继承。

示例:

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

Parent.prototype.sayHello = function() {
  console.log('父类说你好');
};

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

Child.prototype = new Parent();

const child = new Child('子类');

console.log(child.name); // 子类
child.sayHello(); // 父类说你好

组合式继承

组合式继承是原型链继承和借助构造函数继承的组合。这种继承方式既能够访问父类的构造函数,又能够修改父类的属性和方法,同时还能够实现多重继承。

优点:

  • 能够访问父类的构造函数。
  • 能够修改父类的属性和方法。
  • 支持多重继承。

缺点:

  • 实现相对复杂。

示例:

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

Parent.prototype.sayHello = function() {
  console.log('父类说你好');
};

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

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

const child = new Child('子类');

console.log(child.name); // 子类
child.sayHello(); // 父类说你好

原型式继承

原型式继承是一种通过直接复制父类的原型对象来实现继承的方式。这种继承方式非常简单易懂,而且能够实现多重继承。

优点:

  • 实现简单,易于理解和使用。
  • 支持多重继承。

缺点:

  • 无法访问父类的构造函数。
  • 无法修改父类的属性和方法。

示例:

const parent = {
  name: '父类',
  sayHello: function() {
    console.log('父类说你好');
  }
};

const child = Object.create(parent);
child.name = '子类';

console.log(child.name); // 子类
child.sayHello(); // 父类说你好

寄生式继承

寄生式继承是一种通过创建一个新的对象来继承父类的属性和方法,然后将这个新对象作为子类的原型对象的方式。这种继承方式能够访问父类的构造函数,并且能够修改父类的属性和方法。

优点:

  • 能够访问父类的构造函数。
  • 能够修改父类的属性和方法。

缺点:

  • 实现相对复杂。

示例:

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

Parent.prototype.sayHello = function() {
  console.log('父类说你好');
};

function Child(name) {
  const parent = new Parent(name);
  return Object.create(parent);
}

const child = new Child('子类');

console.log(child.name); // 子类
child.sayHello(); // 父类说你好

寄生组合式继承

寄生组合式继承是寄生式继承和组合式继承的组合。这种继承方式既能够访问父类的构造函数,又能够修改父类的属性和方法,同时还能够实现多重继承。

优点:

  • 能够访问父类的构造函数。
  • 能够修改父类的属性和方法。
  • 支持多重继承。

缺点:

  • 实现相对复杂。

示例:

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

Parent.prototype.sayHello = function() {
  console.log('父类说你好');
};

function Child(name) {
  const parent = new Parent(name);
  const child = Object.create(parent);
  child.constructor = Child;
  return child;
}

const child = new Child('子类');

console.log(child.name); // 子类
child.sayHello(); // 父类说你好

混入方式继承

混入方式继承是一种通过将一个对象的属性和方法复制到另一个对象来实现继承的方式。这种继承方式非常简单易懂,而且能够实现多重继承。

优点:

  • 实现简单,易于理解和使用。
  • 支持多重继承。

缺点:

  • 无法访问父类的构造函数。
  • 无法修改父类的属性和方法。

示例:

const parent = {
  name: '父类',
  sayHello: function() {
    console.log('父类说你好');
  }
};

const child = Object.assign({}, parent);
child.name = '子类';

console.log(child.name); // 子类
child.sayHello(); // 父类说你好

ES6 extends

ES6引入了extends,支持直接使用关键字进行类继承,使继承的语法更加简洁。

优点:

  • 语法简洁,易于理解和使用。
  • 支持多重继承。

缺点:

  • 不支持私有继承。

示例:

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

  sayHello() {
    console.log('父类说你好');
  }
}

class Child extends Parent {
  constructor(name) {
    super(name);
  }
}

const child = new Child('子类');

console.log(child.name); // 子类
child.sayHello(); // 父类说你好

总结

JavaScript中提供了多种继承方式,每种继承方式都有其自身的优缺点。开发者可以根据自己的需求选择最合适的继承方式。

参考文献