MST

星途 面试题库

面试题:JavaScript组合继承的优缺点及改进方案

说明JavaScript组合继承的工作方式,分析它存在哪些优点和缺点。如果让你对组合继承进行改进以克服其缺点,你会怎么做?请给出改进的思路和关键代码片段。
18.1万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

组合继承的工作方式

  1. 原型链继承:通过将子类的原型指向父类的实例,实现子类对父类原型属性和方法的继承。例如:
function Parent() {
    this.value = 1;
}
Parent.prototype.getValue = function() {
    return this.value;
};
function Child() {
    this.childValue = 2;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
  1. 借用构造函数继承:在子类构造函数内部调用父类构造函数,实现子类对父类实例属性的继承。例如:
function Child() {
    Parent.call(this);
    this.childValue = 2;
}

优点

  1. 既继承了原型上的方法:保证了函数复用,多个实例共享父类原型上的方法,节省内存。
  2. 又继承了实例属性:每个子类实例都有自己独立的属性,互不干扰。

缺点

  1. 父类构造函数被调用两次:一次是在 Child.prototype = new Parent(); 创建子类原型时,另一次是在 Parent.call(this); 子类构造函数内部。这导致了不必要的性能开销,父类实例属性会在子类原型和子类实例上各创建一份。

改进思路

  1. 寄生组合继承:不通过 new Parent() 创建子类原型,而是通过创建一个临时构造函数,将其原型指向父类原型,然后将子类原型指向这个临时构造函数的实例。这样既避免了父类构造函数的重复调用,又能正确建立原型链。

关键代码片段

function Parent() {
    this.value = 1;
}
Parent.prototype.getValue = function() {
    return this.value;
};
function Child() {
    Parent.call(this);
    this.childValue = 2;
}
// 寄生组合继承核心代码
function inheritPrototype(subType, superType) {
    let prototype = Object.create(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
inheritPrototype(Child, Parent);