有關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