MST

星途 面试题库

面试题:JavaScript 原型链与继承机制的深度剖析

在 JavaScript 中,通过原型链实现继承有多种方式,如构造函数绑定、原型式继承、寄生式继承、寄生组合式继承等。请详细说明寄生组合式继承的原理,并指出它相较于其他继承方式的优势在哪里,同时用代码实现一个简单的寄生组合式继承示例。
21.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

寄生组合式继承的原理

  1. 核心思想:通过构造函数来继承属性,通过原型链来继承方法,避免了不必要的属性复制,同时保持原型链的正确性。
  2. 具体实现步骤
    • 创建一个临时性的构造函数。
    • 将这个临时性构造函数的原型指向父类的原型。
    • 创建一个新的对象,这个对象的原型是上面临时性构造函数的实例,这个新对象就是子类的原型对象。
    • 将子类的构造函数的原型设置为上面创建的新对象。
    • 在子类的构造函数中调用父类的构造函数,以便继承父类的属性。

相较于其他继承方式的优势

  1. 避免不必要的属性复制:不像构造函数绑定那样,在每个实例上都复制父类的属性,寄生组合式继承只在原型链上设置方法,实例共享这些方法,节省内存。
  2. 保持原型链的正确性:与原型式继承和寄生式继承相比,寄生组合式继承能正确地构建原型链,使得 instanceof 和 isPrototypeOf 操作符能正常工作。

代码实现

// 父类
function Parent(name) {
    this.name = name;
    this.sayName = function () {
        console.log('My name is'+ this.name);
    };
}

// 子类
function Child(name, age) {
    // 继承属性
    Parent.call(this, name);
    this.age = age;
}

// 继承方法
(function () {
    // 创建一个临时性的构造函数
    const Temp = function () {};
    // 将临时性构造函数的原型指向父类的原型
    Temp.prototype = Parent.prototype;
    // 创建子类的原型对象
    const childPrototype = new Temp();
    // 设置子类的构造函数的原型
    Child.prototype = childPrototype;
    // 修复构造函数指向
    Child.prototype.constructor = Child;
})();

// 测试
const child = new Child('John', 25);
child.sayName(); // 输出: My name is John
console.log(child.age); // 输出: 25