原型繼承
function SuperType () {
this.property = true;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
};
function SubType () {
this.subProperty = false;
}
// 繼承SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubType = function () {
return this.subProperty;
};
var instance = new SubType();
// 原型鏈的問題
-- 包含引用類型值的原型屬性會被所有的實例共享,通過原型來實現(xiàn)繼承時楣责,原型實際上會變成另一個類型的實例竖般,于是原先的實力屬性也就順理成章的變成了現(xiàn)在的原型屬性了
function SuperType () {
this.colors = ['red', 'yellow', 'green'];
}
function SubType () {}
// 繼承SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push('black');
var instance2 = new SubType(); // red,yellow,green,black
-- 創(chuàng)建子類型的實例的時候认然,不能像超類型的構造函數(shù)中傳遞參數(shù)
借用構造函數(shù)
// 借用構造函數(shù)
function SuperType () {
this.color = ['red', 'blue', "green"];
}
function SubType () {
// 繼承SuperType
SuperType.call(this);
}
借調了超類的構造函數(shù)饺汹,在新創(chuàng)建的SubType實例的環(huán)境下調用了SuperType構造函數(shù)力惯,在新的SubType對象上執(zhí)行了SuperType()函數(shù)中定義了所有的對象初始化代碼璃俗,結果每一個SubType的每一個實例都會具有自己的colors屬性副本了
優(yōu)勢:
子類構造函數(shù)可以向父類構造函數(shù)傳遞參數(shù)
缺點:
方法都在構造函數(shù)中定義套利,因此函數(shù)復用就無從談起了
組合繼承
// 組合繼承
function SuperType (name) {
this.name = name;
this.colors = ["red", "black", "blue"];
}
function SubType() {
SuperType.call(this);
}
SubType.prototype = new SuperType();
不同的SubType實例既分別擁有自己的屬性推励,又可以使用相同的方法了
原型式繼承
function object(o) {
function F() {};
F.prototype = o;
return new F();
}
不過引用類型值得屬性始終都會共享相應的值
寄生式繼承
創(chuàng)建一個封裝繼承過程的函數(shù),該函數(shù)在內部以某種方式來增強對象肉迫,最后再像是它真的做了所有工作一樣返回對象验辞。
function createAnother(origin) {
var clone = object(origin);
clone.sayHi = function () {
//...
}
return clone;
}
寄生組合繼承
優(yōu)點: 因為組合繼承最大的問題是無論什么情況下,都會調用兩次超類構造函數(shù) 一次是創(chuàng)建子類原型的時候喊衫,另外一次就是在子類型構造函數(shù)內部跌造。
寄生組合繼承原理:
通過借用構造函數(shù)來繼承屬性,通過原型鏈的混成形式來繼承方法
不必為了指定子類型的原型而調用超類型的構造函數(shù),所需要的無非是超類型原型的一個副本而已壳贪。
function inheritPrototype(subType, superType) {
var prototype = object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}