继承的实现方式之 寄生组合式继承(Parasitic Combination Inheritance)

普通的组合继承模式中,我们两次调用了父类的构造函数,导致父类的实例属性在子类实例和子类原型上同时存在。主要问题在于在第一次调用时,我们将一个父类实例作为子类的原型,使得父类的实例属性不必要的被复制到了子类原型上。

理想的效果是,只将子类原型的[[Prototype]]隐式属性指向父类原型,不在原型上添加父类的实例属性。由于子类原型的[[Prototype]]是一个隐式属性,直接使用“__proto__”访问不是一个很好的实现方式,我们可以使用寄生模式,先创建一个以父类原型为原型的对象,再用这个对象替换原来的子类原型。

function object(o){
    function F(){}
    F.prototype = o;
    return new F();
}

function inheritPrototype(SubType, SuperType){
    //创建一个以SuperType的原型为原型的对象
    let prototype = object(SuperType.prototype);
    //用该对象取代SubType原有的原型
    prototype.constructor = SubType;
    SubType.prototype = prototype;
}


function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue"];
}
SuperType.prototype.sayName = function(){
    console.log(this.name);
}

function SubType(name, age){
    SuperType.call(this, name);
    this.age = age;
}

// 其实我们就是想实现SubType.prototype.__proto__ = SuperType.prototype;
inheritPrototype(SubType, SuperType);
console.log(SubType.prototype);

SubType.prototype.sayAge = function(){
    console.log(this.age);
}

let instance = new SubType("Jack", 18);
instance.sayName();

这样以来,SuperType()构造函数只调用了一次,用于继承父类的实例属性,避免了在Subtype的原型上有冗余的属性。

posted @ 2020-07-15 08:30  studystudyxinxin  阅读(159)  评论(0)    收藏  举报