簡單談談JavaScript寄生式組合繼承
組合繼承
組合繼承也被稱為偽經典繼承,它綜合了我們昨天說的原型鏈和盜用構造函數,將倆者的有點結合在了一起。它的基本思想是使用原型鏈繼承原型上的屬性和方法,通過盜用構造函數繼承實例屬性,這樣的好處就是可以把方法定義在原型上復用,每個實例又有自己的屬性。
function SuperType (name) {
this.name = name;
this.colors = ["red","yellow","bule"];
}
SuperType.prototype.sayName = function(){
console.log(this.name)
}
function SubType(name,age){
SuperType.call(this,name);
this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function(){
console.log(this.age);
}
let instancel = new SubType("jackson",22);
instancel.colors.push("pink");
instancel.sayName(); // "jackson"
instancel.sayAge();//22
console.log(instancel.colors);// ["red", "yellow", "bule", "pink"]
let instance2 = new SubType("bear", 20);
console.log(instance2.colors); // ["red", "yellow", "bule"]
instance2.sayName(); // "bear";
instance2.sayAge(); // 20
上面的代碼大家有沒有一種豁然開朗的感覺,SubType調用SuperType,并且傳入name,然后定義自己的屬性age,此外SubType.prototype也被賦值位SuperType實例。原型賦值后又在這個原型上添加sayage方法,這樣創(chuàng)建倆個subType實例,這倆個實例都有自己屬性,還可以共享相同的方法。
組合繼承彌補了原型鏈和盜用構造函數的不足,是js中使用最多的繼承模式。
寄生式繼承
寄生式繼承就是用一個函數包裝一個對象,然后返回這個函數的調用,這個函數就變成了個可以隨意增添屬性的實例或對象。object.create()就是這個原理。
// 寄生式繼承
function subobject(obj) {
let clone = Object(obj);
clone.sayName = function(){
console.log("jackson")
};
return clone;
}
let sub = {
name:"bear"
}
let sup = subobject(sub);
sup.sayName();//jackson
這個例子基于sub對象返回一個新對象,返回的sup對象有sub的屬性和方法,還有一個新方法sayName()。
寄生式繼承同樣適合主要關注對象,而不在乎類型和構造函數的場景。object()函數不是寄生式繼承所必需的,任何返回新對象的函數都可以在這里使用。
注意 通過寄生式繼承給對象添加函數會導致函數難以重用,與構造函數模式類似。
寄生式組合繼承
組合繼承存在這一定的效率問題,它的父類構造函數始終會被調用倆次,一次在創(chuàng)建字類原型時調用,另一次在子類構造函數中調用。本質上子類只需要在執(zhí)行時重寫自己的原型就行了。
function inheritPrototype(subType, superType) {
let prototype = Object(superType.prototype); // 創(chuàng)建對象
prototype.constructor = subType; // 增強對象
subType.prototype = prototype; // 賦值對象
}
這個 inheritPrototype()函數實現了寄生式組合繼承的核心邏輯。這個函數接收兩個參數:子類構造函數和父類構造函數。在這個函數內部,第一步是創(chuàng)建父類原型的一個副本。然后,給返回的 prototype 對象設置 constructor 屬性,解決由于重寫原型導致默認 constructor 丟失的問題。最后將新創(chuàng)建的對象賦值給子類型的原型。如下例所示,調用 inheritPrototype()就可以實現前面例子中的子類型原型賦值:
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function () {
console.log(this.name);
};
function SubType(name, age) {
SuperType.call(this, name);
this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function () {
console.log(this.age);
};
這里只調用了一次 SuperType 構造函數,避免了 SubType.prototype 上不必要也用不到的屬性, 因此可以說這個例子的效率更高。而且原型鏈仍然保持不變。
總結
到此這篇關于JavaScript寄生式組合繼承的文章就介紹到這了,更多相關JS寄生式組合繼承內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

