2021-02-19 08:52:21
在 JavaScript 中,实现继承的核心方式包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承和寄生组合式继承。以下是具体实现方法及优缺点分析:

通过将子类型的原型指向父类型的实例实现继承。
function Parent() { this.name = 'Parent'; this.colors = ['red', 'blue', 'green'];}Parent.prototype.sayName = function() { console.log(this.name);};function Child() { this.childName = 'Child';}Child.prototype = new Parent(); // 关键:子类型原型指向父类型实例Child.prototype.constructor = Child; // 修正constructor指向let child1 = new Child();child1.colors.push('black');let child2 = new Child();console.log(child2.colors); // ["red", "blue", "green", "black"]子类型实例共享父类型原型上的引用类型属性(如colors数组)。
无法向父类构造函数传递参数。
通过在子类型构造函数中调用父类型构造函数实现继承。
function Parent(name) { this.name = name; this.colors = ['red', 'blue', 'green']; this.sayName = function() { console.log(this.name); };}function Child(name) { Parent.call(this, name); // 关键:调用父类型构造函数 this.childName = 'Child';}let child1 = new Child('Child1');child1.colors.push('black');let child2 = new Child('Child2');console.log(child2.colors); // ["red", "blue", "green"]子类型实例拥有独立的属性(如colors数组)。
可向父类构造函数传递参数。
父类型方法定义在构造函数中,每次创建实例都会重新创建方法,无法复用。
无法访问父类型原型上的属性和方法。
结合原型链继承和构造函数继承的优点。
function Parent(name) { this.name = name; this.colors = ['red', 'blue', 'green'];}Parent.prototype.sayName = function() { console.log(this.name);};function Child(name, age) { Parent.call(this, name); // 构造函数继承 this.age = age;}Child.prototype = new Parent(); // 原型链继承Child.prototype.constructor = Child;let child1 = new Child('Child1', 10);child1.colors.push('black');let child2 = new Child('Child2', 12);console.log(child2.colors); // ["red", "blue", "green"]父类型方法可复用。
子类型实例拥有独立属性。
可向父类构造函数传递参数。
基于现有对象创建新对象,适用于无需自定义类型的场景。
let person = { name: 'Person', friends: ['Shelby', 'Court', 'Van']};let anotherPerson = Object.create(person); // 关键:基于person创建新对象anotherPerson.name = 'Greg';anotherPerson.friends.push('Rob');console.log(person.friends); // ["Shelby", "Court", "Van", "Rob"]在原型式继承基础上增强对象,适合临时扩展功能。
function createAnother(original) { let clone = Object.create(original); // 创建新对象 clone.sayHi = function() { // 增强对象 console.log('hi'); }; return clone;}let person = { name: 'Person', friends: ['Shelby', 'Court', 'Van']};let anotherPerson = createAnother(person);anotherPerson.sayHi(); // "hi"通过继承父类原型的副本来避免构造函数重复调用。
function inheritPrototype(child, parent) { let prototype = Object.create(parent.prototype); // 创建父类原型副本 prototype.constructor = child; // 修正constructor指向 child.prototype = prototype; // 赋值给子类原型}function Parent(name) { this.name = name; this.colors = ['red', 'blue', 'green'];}Parent.prototype.sayName = function() { console.log(this.name);};function Child(name, age) { Parent.call(this, name); // 构造函数继承 this.age = age;}inheritPrototype(Child, Parent); // 关键:继承父类原型副本let child1 = new Child('Child1', 10);child1.colors.push('black');let child2 = new Child('Child2', 12);console.log(child2.colors); // ["red", "blue", "green"]避免父类构造函数重复调用,性能最优。
结合了原型链继承和构造函数继承的优点。

根据需求选择合适的继承方式,可平衡代码简洁性、性能和可维护性。