第一次完整看一遍(JavaScript設計模式)該模式的介紹,感覺這不就是繼承而已嗎,只不過可能是部分繼承。 混入(Mixin)模式 定義: Mixin是可以輕鬆被一個子類或一組子類繼承功能的類,目的是函數復用。繼承Mixin是擴展功能的方式,另外也可能從多個Mixin類進行繼承。 繼承方式: 這個 ...
第一次完整看一遍(JavaScript設計模式)該模式的介紹,感覺這不就是繼承而已嗎,只不過可能是部分繼承。
混入(Mixin)模式
定義:
Mixin是可以輕鬆被一個子類或一組子類繼承功能的類,目的是函數復用。繼承Mixin是擴展功能的方式,另外也可能從多個Mixin類進行繼承。
繼承方式:
這個模式關鍵點在於繼承,JavaScript上有幾種實現繼承的方式:
1. 原型繼承
function A(){ this.name = "A"; } function B(){ } B.prototype= new A(); var b = new B(); console.log(b instanceof A); //true console.log(b instanceof B); //true
PS:無法實現多繼承。
2. 拷貝繼承
function extend(receiveClass, givingClass){ for(var key in givingClass.prototype){ receiveClass.prototype[key] = givingClass.prototype[key]; } } function A(){ } A.prototype.hello = function(){ console.log("hello"); } function B(){ } extend(B, A); var b = new B(); console.log(b instanceof A); //false console.log(b instanceof B); //true
PS:支持多繼承,但效率低。
3. 構造繼承
function A1(){ this.name = "A"; } function A2(){ this.age = 18; } function B(){ A1.call(this); A2.call(this); this.desc = "Test"; } var b = new B(); console.log(b instanceof A); //false console.log(b instanceof B); //true
PS:支持多繼承
4. 實例繼承
function A(){ this.name = "A"; } function B(){ var instance = new A(); instance.desc = "Test"; return instance; } var b = new B(); console.log(b instanceof A); //true console.log(b instanceof B); //false
PS:這種方式我覺得很糟糕,生成的對象本質是父類的實例,不是子類的對象,當然也不支持多繼承。
例子:
// Define a simple Car constructor var Car = function ( settings ) { this.model = settings.model || "no model provided"; this.color = settings.color || "no colour provided"; }; // Mixin var Mixin = function () {}; Mixin.prototype = { driveForward: function () { console.log( "drive forward" ); }, driveBackward: function () { console.log( "drive backward" ); }, driveSideways: function () { console.log( "drive sideways" ); } }; // Extend an existing object with a method from another function augment( receivingClass, givingClass ) { // only provide certain methods if ( arguments[2] ) { for ( var i = 2, len = arguments.length; i < len; i++ ) { receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]]; } } else { for ( var methodName in givingClass.prototype ) { if ( !Object.hasOwnProperty.call(receivingClass.prototype, methodName) ) { receivingClass.prototype[methodName] = givingClass.prototype[methodName]; } } } } augment( Car, Mixin, "driveForward", "driveBackward" ); var myCar = new Car({ model: "Ford Escort", color: "blue" }); myCar.driveForward(); myCar.driveBackward(); augment( Car, Mixin ); var mySportsCar = new Car({ model: "Porsche", color: "red" }); mySportsCar.driveSideways();
這個例子裡面Car類所擴展的功能,是通過拷貝繼承的繼承方式繼承的。
優點:
1. 減少系統中的重覆功能及增加函數復用。
缺點:
1. 將功能註入對象原型中,會導致原型污染和函數起源方面的不確定性。
PS:簡單說就是找不到擴展的方法的來源。
結論:
混入模式是一種簡單的結構型模式,目的是擴展子類功能,子類可從多個Mixin類收集功能。
參考文獻
1. http://raychase.iteye.com/blog/1337415 (JavaScript實現繼承的幾種方式)
2. 《JavaScript設計模式》by 徐濤【譯】
本文為原創文章,轉載請保留原出處,方便溯源,如有錯誤地方,謝謝指正。
本文地址 :http://www.cnblogs.com/lovesong/p/5617570.html