天天看點

javascript 的七種繼承方式(三)組合繼承

組合繼承

前面兩篇我們了解到:原型鍊繼承存在着引用類型問題,而借用構造函數又無法實作函數複用和原型方法繼承的問題。那麼能不能把兩者結合一下,取其精華,棄其糟粕?答案是肯定的。那就是接下來我們要介紹的組合繼承。

組合繼承有時候也叫做僞經典繼承,指的是将原型鍊和借用構造函數的技術組合到一起,進而發揮二者之長的一種繼承模式。其思路就是使用原型鍊實作對原型屬性和方法的繼承。而通過借用構造函數來實作對執行個體屬性的繼承。這樣既通過在原型上定義方法實作函數複用,又能保證每個執行個體都有它自己的屬性。下面來看一個例子

function Father(name){
    this.name = name;
    this.colors = ['red','pink','green'];
}

Father.prototype.sayName = function(){
    console.log(this.name)
}

function Son(name, age){
    //屬性繼承
    Father.call(this, name);
    this.age = age;
}

//方法繼承
Son.prototype = new Father();
Son.prototype.sayAge = function(){
    console.log(this.age);
}


var son1 = new Son('Alvin', 28);
son1.colors.push('yellow');
console.log(son1.colors); // red,pink,green,yellow
son1.sayName(); //Alvin
son2.sayAge(); //28


var son2 = new Son('Semon', 29);
console.log(son2.colors);//red,pink,green
son2.sayName(); //Semon
son2.sayAge(); //29
           

在這個例子中,Father構造函數定義了兩個屬性:name和colors, Father的原型定義了一個方法sayName()。Son構造函數在調用Father的構造函數時傳入了name參數,緊接着又定義了它自己的屬性age。然後将Father的執行個體指派給Son的原型,然後又在該新原型上定義了方法sayAge()。這樣一來就可以讓兩個不同的Son執行個體既分别擁有自己的屬性,又可以使用相同的方法了。

組合繼承避免了原型鍊和借用構造函數的缺陷,融合了它們的有點,成為JavaScript中最長用的繼承模式。

繼續閱讀