摘要:源碼地址什么是一般翻譯為混入混合,早期一般解釋為把一個(gè)對(duì)象的方法和屬性拷貝到另一個(gè)對(duì)象上也可以簡(jiǎn)單理解為能夠被繼承的類(lèi),最終目的是實(shí)現(xiàn)代碼的復(fù)用。
Github 源碼地址
什么是mixinmixin一般翻譯為“混入”、“混合”,
早期一般解釋為:把一個(gè)對(duì)象的方法和屬性拷貝到另一個(gè)對(duì)象上;
也可以簡(jiǎn)單理解為能夠被繼承的類(lèi),
最終目的是實(shí)現(xiàn)代碼的復(fù)用。
為了使你能夠最快的清楚我在說(shuō)什么,我們從一個(gè)需求說(shuō)起:
一個(gè)項(xiàng)目中有多個(gè)彈層需求;
一些是公共方法,比如點(diǎn)擊關(guān)閉按鈕關(guān)閉彈層;
一些彈層是可以拖動(dòng)的,且有蒙層;
一些彈層是可以縮放的;
其他都是業(yè)務(wù)方法,無(wú)可復(fù)用性。
你可以先在心里想下,如果是你,你會(huì)怎樣完成這個(gè)需求?
腦海中規(guī)劃下我們?yōu)楣卜椒▽?xiě)個(gè)類(lèi):BaseModal
為可拖動(dòng)的彈層寫(xiě)個(gè)類(lèi):DragModal
為可縮放的彈層寫(xiě)個(gè)類(lèi):ScaleModal
為自定義的業(yè)務(wù)需求寫(xiě)個(gè)類(lèi):CustomModal
畫(huà)個(gè)腦圖的話,會(huì)是下面圖片中的樣子:
extends簡(jiǎn)單實(shí)現(xiàn)下 看代碼// 公共方法 class BaseModal { close(){ console.log("close"); } } // 可以拖動(dòng)的彈層,我們寫(xiě)一個(gè)多帶帶的類(lèi) class DragModal extends BaseModal { hasLayer = true; drag() { console.log("drag"); } } // 可以縮放的彈層,我們寫(xiě)一個(gè)多帶帶的類(lèi) class ScaleModal extends BaseModal { scale() { console.log("scale"); } } // 業(yè)務(wù)方法 class CustomModal extends DragModal { close(){ console.log("custom-close"); } do() { console.log("do"); } } let c = new CustomModal(); c.close(); // custom-close c.drag(); // drag c.do(); // do c.hasLayer; // true拋出問(wèn)題
如何使CustomModal能夠同時(shí)繼承DragModal和ScaleModal?
某個(gè)相同方法希望不覆蓋,而是都執(zhí)行
試試早期的mixin方法實(shí)現(xiàn)多繼承 看代碼// 可以拖動(dòng)的彈層,我們寫(xiě)一個(gè)多帶帶的類(lèi) class DragModal extends BaseModal { hasLayer = true; drag() { console.log("drag"); } } // 可以縮放的彈層,我們寫(xiě)一個(gè)多帶帶的類(lèi) class ScaleModal extends BaseModal { scale() { console.log("scale"); } } // 獲取原型對(duì)象的所有屬性和方法 function getPrototypes(ClassPrototype) { return Object.getOwnPropertyNames(ClassPrototype).slice(1); } function mix(...mixins){ return function(target){ if (!mixins || !Array.isArray(mixins)) return target; let cp = target.prototype; for (let C of mixins) { let mp = C.prototype; for (let m of getPrototypes(mp)) { cp[m] = mp[m]; } } } } @mix(DragModal, ScaleModal) class CustomModal { scale(){ console.log("custom-scale"); } do() { console.log("do"); } } let c = new CustomModal(); c.close(); // 報(bào)錯(cuò),因?yàn)閐obase沒(méi)在A或B的prototype上,而是在A.prototype.__proto__上 c.drag(); // drag c.scale(); // scale 并非是我們想要的custom-scale console.log(c.hasLayer); // undefined存在的問(wèn)題
以上mix方式實(shí)現(xiàn)了多繼承,但存在以下問(wèn)題
會(huì)修改target類(lèi)的原型對(duì)象
target類(lèi)的相同方法名會(huì)被被繼承類(lèi)的相同方法名覆蓋
實(shí)例屬性無(wú)法繼承
BaseModal類(lèi)無(wú)法被繼承
只繼承不修改prototype的實(shí)現(xiàn)方式 看代碼class BaseModal { close() { console.log("close"); } } let DragModalMixin = (extendsClass) => class extends extendsClass { hasLayer = true; drag() { console.log("drag"); } }; class CustomModal extends DragModalMixin(BaseModal) { drag() { console.log("custom-drag"); } do() { console.log("do"); } } let c = new CustomModal(); c.close(); // close c.drag(); // custom-drag console.log(c.hasLayer); // true存在的問(wèn)題
如何讓CustomModal再繼承ScaleModal呢?
其實(shí)很簡(jiǎn)單,在上面基礎(chǔ)上,我們?cè)賹?xiě)一個(gè)ScaleModalMixinMixin類(lèi)就可以了
class BaseModal { close() { console.log("close"); } } let DragModalMixin = (extendsClass) => class extends extendsClass { hasLayer = true; drag() { console.log("drag"); } }; let ScaleModalMixin = (extendsClass) => class extends extendsClass { scale() { console.log("scale"); } }; class CustomModal extends ScaleModalMixin(DragModalMixin(BaseModal)) { drag() { console.log("custom-drag"); } do() { console.log("do"); } } let c = new CustomModal(); c.close(); // close c.drag(); // custom-drag c.scale(); // scale console.log(c.hasLayer); // true存在的問(wèn)題
這種方式不會(huì)修改父類(lèi)的原型對(duì)象,但是如果存在跟父類(lèi)同名的方法,只會(huì)執(zhí)行父類(lèi)的,而不回執(zhí)行被繼承的類(lèi)的方法,那么如何使相同方法分別執(zhí)行呢?
super實(shí)現(xiàn)相同方法不覆蓋 看代碼class BaseModal { close() { console.log("close"); } } let DragModalMixin = (extendsClass) => class extends extendsClass { hasLayer = true; drag() { console.log("drag"); } }; let ScaleModalMixin = (extendsClass) => class extends extendsClass { scale() { console.log("scale"); } close() { console.log("scale-close"); if (super.close) super.close(); } }; class CustomModal extends ScaleModalMixin(DragModalMixin(BaseModal)) { close() { console.log("custom-close"); if (super.close) super.close(); } do() { console.log("do"); } } let c = new CustomModal(); c.close(); // custom-close -> scale-close -> close總結(jié)
Mixin是一種思想,用來(lái)實(shí)現(xiàn)代碼高度可復(fù)用性,又可以用來(lái)解決多繼承的問(wèn)題,是一種非常靈活的設(shè)計(jì)模式,如果你多多琢磨,相信你也會(huì)發(fā)現(xiàn)一些其他的妙用的,看好你喲!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95713.html
摘要:一般的做法是把這些動(dòng)作寫(xiě)在和的兩個(gè)方法里,單元測(cè)試框架會(huì)負(fù)責(zé)在開(kāi)始和結(jié)束的時(shí)候調(diào)用這兩個(gè)方法。從視覺(jué)上無(wú)法直觀的指導(dǎo)原來(lái)和是一對(duì)的。然后再把這個(gè)小的上下文附著到主測(cè)試邏輯上這里利用了單元測(cè)試的的特性,把轉(zhuǎn)化為回調(diào)在的時(shí)候就設(shè)置好。 很多測(cè)試都需要在啟動(dòng)的時(shí)候做一些事情,然后在結(jié)束的時(shí)候再把做的事情給清理了。一般的做法是把這些動(dòng)作寫(xiě)在setUp和tearDown的兩個(gè)方法里,單元測(cè)試框架...
摘要:最近新開(kāi)了一個(gè)項(xiàng)目,采用來(lái)開(kāi)發(fā),在數(shù)據(jù)庫(kù)及路由管理方面用了不少的裝飾器,發(fā)覺(jué)這的確是一個(gè)好東西。在中的使用該裝飾器會(huì)在定義前調(diào)用,如果函數(shù)有返回值,則會(huì)認(rèn)為是一個(gè)新的構(gòu)造函數(shù)來(lái)替代之前的構(gòu)造函數(shù)。函數(shù)參數(shù)裝飾器最后,還有一個(gè)用于函數(shù)參 最近新開(kāi)了一個(gè)Node項(xiàng)目,采用TypeScript來(lái)開(kāi)發(fā),在數(shù)據(jù)庫(kù)及路由管理方面用了不少的裝飾器,發(fā)覺(jué)這的確是一個(gè)好東西。 裝飾器是一個(gè)還處于草案中...
摘要:想要使用語(yǔ)法的話,配合,這個(gè)插件,體驗(yàn)更佳,這個(gè)插件在語(yǔ)法中實(shí)現(xiàn)了。這種方式最接近的單文件組件的寫(xiě)法,如果一個(gè)完善項(xiàng)目從改成,用這種方法很快,只要加上和一些必要的變量類(lèi)型就好了,然后用包裹就好。不推薦混入用這種方式寫(xiě),無(wú)法實(shí)現(xiàn)多繼承。 最近嘗試了一下 TypeScript,試著把一個(gè) Vue 項(xiàng)目改成了 TypeScript 的,感覺(jué)還不錯(cuò) 目前 Vue 和 TypeScript 的配...
摘要:在下實(shí)現(xiàn)圓角效果由于兼容性特別差,所以要在低版本瀏覽器下實(shí)現(xiàn)圓周角效果特別難利用的效果可實(shí)現(xiàn)如下圖所示的圓效果代碼簡(jiǎn)單如下制作三杠效果其實(shí)就是利用特性變色我們?cè)谧鋈缦聢D標(biāo)時(shí),一般情況下時(shí)會(huì)有三處變色但是利用繼承自這一特性 在ie下實(shí)現(xiàn)圓角效果 (由于border-radius兼容性特別差,所以要在ie低版本瀏覽器下實(shí)現(xiàn)圓周角效果特別難)利用border-style的dotted效果可實(shí)...
摘要:變量插值預(yù)處理器中定義的變量不僅可以用作屬性值,還可以用作選擇器,屬性名等,這就是變量插值。三種預(yù)處理器的嵌套語(yǔ)法是一致的,引用父級(jí)選擇器的標(biāo)記也相同。三種預(yù)處理器的使用方式的差異比較大,下面分別說(shuō)明。 在寫(xiě)CSS的時(shí)候我們會(huì)發(fā)現(xiàn),為了兼容瀏覽器等原因,我們往往需要寫(xiě)很多冗余的代碼,CSS預(yù)處理器就是為了解決CSS的這些問(wèn)題,簡(jiǎn)化CSS代碼的編寫(xiě)。 目前最主流的CSS預(yù)處理器是LESS...
閱讀 2113·2021-11-18 10:02
閱讀 2863·2021-09-04 16:41
閱讀 1155·2019-08-30 15:55
閱讀 1420·2019-08-29 17:27
閱讀 1105·2019-08-29 17:12
閱讀 2539·2019-08-29 15:38
閱讀 2864·2019-08-29 13:02
閱讀 2841·2019-08-29 12:29