JS 寄生组合式继承,为什么要给Child.prototype赋值Object.create(Parent.prototype),直接赋值Parent.prototype不行吗
在 JavaScript 中,寄生组合式继承是一种常见的继承模式,它结合了原型链继承和借用构造函数继承的优点。具体来说,寄生组合式继承通过以下步骤实现:
Object.create
创建一个新的对象,这个对象的原型指向父类的原型。constructor
属性,使其指向子类自身。下面是一个示例代码:
function Parent(name) {
this.name = name;
}
Parent.prototype.sayName = function() {
console.log(this.name);
};
function Child(name, age) {
Parent.call(this, name); // 借用构造函数继承
this.age = age;
}
// 寄生组合式继承
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
Child.prototype.sayAge = function() {
console.log(this.age);
};
const child = new Child('John', 25);
child.sayName(); // John
child.sayAge(); // 25
Object.create(Parent.prototype)
而不是直接赋值 Parent.prototype
?避免共享原型对象:
如果直接赋值 Child.prototype = Parent.prototype
,那么 Child.prototype
和 Parent.prototype
将引用同一个对象。这意味着对 Child.prototype
的任何修改都会影响到 Parent.prototype
,反之亦然。这会导致意想不到的副作用和错误。
Child.prototype = Parent.prototype;
Child.prototype.sayAge = function() {
console.log(this.age);
};
// 现在 Parent.prototype 也有了 sayAge 方法,这是不期望的
console.log(Parent.prototype.sayAge); // function
正确设置原型链:
使用 Object.create(Parent.prototype)
创建的对象,其原型链会正确地指向 Parent.prototype
,但它是一个全新的对象,不会影响到 Parent.prototype
。这样可以确保子类和父类的原型链关系正确,同时避免了共享原型对象的问题。
constructor 属性的修正:
直接赋值 Child.prototype = Parent.prototype
会导致 Child.prototype.constructor
指向 Parent
,而不是 Child
。这会导致一些问题,特别是在需要依赖 constructor
属性的情况下。使用 Object.create
可以避免这个问题,并且可以手动修正 constructor
属性。
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
综上所述,使用 Object.create(Parent.prototype)
可以避免共享原型对象的问题,并且可以正确设置原型链和 constructor
属性,从而实现更健壮和灵活的继承机制。