寄生组合式继承的原理
- 核心思想:通过构造函数来继承属性,通过原型链来继承方法,避免了不必要的属性复制,同时保持原型链的正确性。
- 具体实现步骤:
- 创建一个临时性的构造函数。
- 将这个临时性构造函数的原型指向父类的原型。
- 创建一个新的对象,这个对象的原型是上面临时性构造函数的实例,这个新对象就是子类的原型对象。
- 将子类的构造函数的原型设置为上面创建的新对象。
- 在子类的构造函数中调用父类的构造函数,以便继承父类的属性。
相较于其他继承方式的优势
- 避免不必要的属性复制:不像构造函数绑定那样,在每个实例上都复制父类的属性,寄生组合式继承只在原型链上设置方法,实例共享这些方法,节省内存。
- 保持原型链的正确性:与原型式继承和寄生式继承相比,寄生组合式继承能正确地构建原型链,使得 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