原型鏈繼承:
引用類型值的原型屬性會被所有實例共享
在創建子類型的實例時,不能向超類型的構造函數中傳遞參數。
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ } //繼承瞭 SuperType SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green,black"
構造函數繼承:解決瞭原型鏈中的兩個問題,但又出現瞭新的問題。
超類型的原型中定義的方法,對子類型而言也是不可見的,方法都在構造函數中定義,因此函數復用就無從談起瞭
組合繼承:解決瞭原型鏈和構造函數繼承的問題,但出現新的問題:
在第一次調用 SuperType 構造函數時,SubType.prototype 會得到兩個屬性: name 和 colors;它們都是 SuperType 的實例屬性,隻不過現在位於 SubType 的原型中。
當調用 SubType 構造函數時,又會調用一次 SuperType 構造函數,這一次又在新對象上創建瞭實例屬性 name 和 colors。於是,這兩個屬性就屏蔽瞭原型中的兩個同名屬性。出現瞭多餘的屬性。
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ SuperType.call(this, name); //第二次調用 SuperType() this.age = age; } SubType.prototype = new SuperType(); //第一次調用 SuperType() SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); };
共享原型:
子類原型和父類原型共享,指向同一個原型對象,修改子類原型會影響父類原型。
function SuperType() { } SuperType.prototype.name = "Tom"; function SubType() { } function inherit(Target,Origin){ Target.prototype = Origin.prototype; } inherit(SubType,SuperType); SubType.prototype.name = "Jack"; var test1 = new SubType(); var test2 = new SuperType(); console.log(test1.name);//Jack console.log(test2.name);//Jack
進行改進:聖杯模式
function SuperType() { } SuperType.prototype.name = "Tom"; function SubType() { } function inherit(Target,Origin){ function F(){}; F.prototype = Origin.prototype Target.prototype = new F(); Target.prototype.constructor = Target; Target.prototype.uber = Origin.prototype; } inherit(SubType,SuperType); SubType.prototype.name = "Jack"; var test1 = new SubType(); var test2 = new SuperType(); console.log(test1.name);//Jack console.log(test2.name);//Tom
Yahoo寫法:利用瞭閉包。
var inherit = (function(Target,Origin){ var F = function(){}; return function(){ F.prototype = Origin.prototype Target.prototype = new F(); Target.prototype.constructor = Target; Target.prototype.uber = Origin.prototype; } }())