JS 繼承:extend、mixin 和 plugin(二)



Mixin:

Mixin 是一種JS實現多繼承方式,它通過復制其他類原型鏈(prototype)上的方法到自身原型鏈(prototype)上,來實現多繼承。根據定義我們可以實現函數:

 /**

  * 將其他類作為mixin集成到指定類上面

  * @param {Function} c 構造函數

  * @param {Array} mixins 擴展類

  * @return {Function} 傳入的構造函數

  */

function mixin(c,mixins){

  var prototype = c.prototype;

  $.each(mixins, function (index,ext) {

if (ext) {

var proto = ext.prototype;

for (var p in proto) {

prototype[p] = proto[p];

}

}

});

return c;

}

有了這個方法,我們來做一下實驗:

  

function A(){};

A.prototype = {

method:function(){

return 'a';

},

methodA:function(){

}

};

function B(){};

B.prototype = {

method:function(){

return 'b';

},

methodB:function(){

}

};

function C(){}

C.prototype = {

method:function(){

return 'c';

},

methodC:function(){

}

};

mixin(C,[A,B]);

var c = new C();

alert(c.method()); //輸出 b

此時我們看到結果是b但是根據繼承的定義,子類的方法覆蓋父類,所以這個結果不是我們想要的。我們需要子類的方法覆蓋minxins 的方法。那么我們繼續更改:

function mixin(c,mixins){

var prototype = {},

   constructors = mixins['concat'](c);

$.each(constructors , function (index,ext) {

if (ext) {

var proto = ext.prototype;

for (var p in proto) {

prototype[p] = proto[p];

}

}

});

$.each(prototype, function (k,v) {

    c.prototype[k] = v;

});

return c;

}

此時再執行上面的結果,

var c = new C();

alert(c.method()); //輸出 c

看上去現在mixin我們完整的實現了,但是如果C本來繼承了Base類,而Base類又有方法跟mixins中的類的方法重復,我們怎么辦:

function Base(){}

Base.prototype = {

method:function(){

return 'base';

},

methodA:function(){

  return 'base';

}

};

function C(){

}

extend(C,Base);

C.prototype.method = function(){

return c

}

mixin(C,[A,B]);

var c = new C();

alert(c.method()); //輸出 c

alert(c.methodA()); //輸出 base

但是從繼承的概念上講,Base沒有繼承mixins中的方法,所以C從minxins中繼承來的方法的優先級應該高於Base類中的方法,所以我們需要覆蓋父類的方法,那么我們minxin 的最終版本是:

function mixin(c,mixins){

var prototype = {},

   constructors = mixins['concat'](c);

$.each(constructors , function (index,ext) {

if (ext) {

var proto = ext.prototype;

for (var p in proto) {

//由於本身的構造函數在最后面,父類的方法不覆蓋mixins中的方法

if (proto.hasOwnProperty(p)) {

             prototype[p] = proto[p];

           }

}

}

});

$.each(prototype, function (k,v) {

    c.prototype[k] = v;

});

return c;

}

小結:

Mixin 在實現JS的繼承是一種非常強大的方式,特別是寫控件時,可以將大量抽象的邏輯封裝成一個個的mixin,我們在實現一個控件時,可以將這些mixins直接引入控件類上,不需要重新編寫實現。后面我會講解一些常見的mixin。

下一節我會講解plugin ,同時對比plugin 跟 mixin的實現場景。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM