JavaScript對寄生組合式繼承的理解

有關JavaScript的幾種繼承方式請移步JavaScript的幾種繼承方式

原型鏈的缺陷

SubType.prototype = new SuperType();

這樣做的話,SuperType構造函數中的屬性也會變成SubType原型中的屬性,而我們需要SubType原型只繼承SuperType原型
還有一點就是引用類型值屬性的共享

寄生組合式繼承的理解

爲了結合原型鏈、組合繼承和寄生式繼承的優點,可以新建一個臨時的類temp,temp.prototype指向父類的Prototype,然後創建一個temp實例,並給它加上一個constructor屬性
這樣,相當於用原型鏈的方法繼承temp,由於temp的構造函數爲空,所以只繼承了原型上的屬性,構造函數上的屬性再用call或apply來繼承

於是,我們可以把封裝繼承的函數進行修改,不使用object()或Object.create(),便於理解

//繼承原型
function inheritPrototype(subType, superType){  //參數爲兩個類型的構造函數  
    var temp = function(){};
    temp.prototype = superType.prototype;
    var tempInstance = new temp();  //創建temp的實例tempInstance

    //給temp的實例tempInstance添加constructor屬性,指向subType,雖然不是真的prototype.constructor,但是用來實現繼承的效果是我們想要的
    tempInstance.constructor = subType;
    subType.prototype = tempInstance;  //原型鏈繼承
}  


function SuperType(name){  
    this.name = name;  
    this.colors = [];  
}  


SuperType.prototype.sayName = function(){};  


function SubType(name, age){
    //繼承構造函數中的屬性  
    SuperType.call(this, name);  
    this.age = age;  
}  


inheritPrototype(SubType, SuperType);  


SubType.prototype.sayAge = function(){};

寄生組合式繼承

不用temp,直接SubType.prototype = SuperType.prototype?

因爲SubType.prototype直接指向了SuperType.prototype,所以改變子類prototype中的屬性的話,父類prototype中的屬性也會被改變

例子:

//子類改變會影響父類的情況

function Animal(){
    this.species = 'animal';
}

Animal.prototype.color = 'red';

function Cat(){
    this.meow = 'meowmeowmeow';
}

function Dog(){
    this.bark = 'bow-wow';
}

Cat.prototype = Animal.prototype;
Dog.prototype = Animal.prototype;

var cat = new Cat();
var dog = new Dog();

console.log(cat.color);  //red
console.log(dog.color);  //red
console.log(Animal.prototype.color);  //red

Cat.prototype.color = 'blue';

console.log(cat.color);  //blue
console.log(dog.color);  //blue
console.log(Animal.prototype.color);  //blue


//修正:將SubType的原型指向temp的一個臨時創建的實例

function Animal(){
    this.species = 'animal';
}

Animal.prototype.color = 'red';

function Cat(){
    Animal.call(this);
    this.meow = 'meowmeowmeow';
}

var temp = function(){};

temp.prototype = Animal.prototype;
var tempInstance = new temp();
tempInstance.constructor = Cat;

Cat.prototype = tempInstance;

var cat = new Cat();

console.log(cat.color);  //red
console.log(Animal.prototype.color);  //red

Cat.prototype.color = 'blue';

console.log(cat.color);  //blue
console.log(Animal.prototype.color);  //red
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章