原型繼承
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();
// 原型鏈的問題
-- 包含引用類型值的原型屬性會被所有的實(shí)例共享,通過原型來實(shí)現(xiàn)繼承時(shí),原型實(shí)際上會變成另一個(gè)類型的實(shí)例,于是原先的實(shí)力屬性也就順理成章的變成了現(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í)候,不能像超類型的構(gòu)造函數(shù)中傳遞參數(shù)
借用構(gòu)造函數(shù)
// 借用構(gòu)造函數(shù)
function SuperType () {
this.color = ['red', 'blue', "green"];
}
function SubType () {
// 繼承SuperType
SuperType.call(this);
}
借調(diào)了超類的構(gòu)造函數(shù),在新創(chuàng)建的SubType實(shí)例的環(huán)境下調(diào)用了SuperType構(gòu)造函數(shù),在新的SubType對象上執(zhí)行了SuperType()函數(shù)中定義了所有的對象初始化代碼,結(jié)果每一個(gè)SubType的每一個(gè)實(shí)例都會具有自己的colors屬性副本了
優(yōu)勢:
子類構(gòu)造函數(shù)可以向父類構(gòu)造函數(shù)傳遞參數(shù)
缺點(diǎn):
方法都在構(gòu)造函數(shù)中定義,因此函數(shù)復(fù)用就無從談起了
組合繼承
// 組合繼承
function SuperType (name) {
this.name = name;
this.colors = ["red", "black", "blue"];
}
function SubType() {
SuperType.call(this);
}
SubType.prototype = new SuperType();
不同的SubType實(shí)例既分別擁有自己的屬性,又可以使用相同的方法了
原型式繼承
function object(o) {
function F() {};
F.prototype = o;
return new F();
}
不過引用類型值得屬性始終都會共享相應(yīng)的值
寄生式繼承
創(chuàng)建一個(gè)封裝繼承過程的函數(shù),該函數(shù)在內(nèi)部以某種方式來增強(qiáng)對象,最后再像是它真的做了所有工作一樣返回對象。
function createAnother(origin) {
var clone = object(origin);
clone.sayHi = function () {
//...
}
return clone;
}
寄生組合繼承
優(yōu)點(diǎn): 因?yàn)榻M合繼承最大的問題是無論什么情況下,都會調(diào)用兩次超類構(gòu)造函數(shù) 一次是創(chuàng)建子類原型的時(shí)候,另外一次就是在子類型構(gòu)造函數(shù)內(nèi)部。
寄生組合繼承原理:
通過借用構(gòu)造函數(shù)來繼承屬性,通過原型鏈的混成形式來繼承方法
不必為了指定子類型的原型而調(diào)用超類型的構(gòu)造函數(shù),所需要的無非是超類型原型的一個(gè)副本而已。
function inheritPrototype(subType, superType) {
var prototype = object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}