<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        新手快速入門JavaScript裝飾者模式與AOP

        來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 21:54:41
        文檔

        新手快速入門JavaScript裝飾者模式與AOP

        新手快速入門JavaScript裝飾者模式與AOP:什么是裝飾者模式 當我們拍了一張照片準備發(fā)朋友圈時,許多小伙伴會選擇給照片加上濾鏡。同一張照片、不同的濾鏡組合起來就會有不同的體驗。這里實際上就應用了裝飾者模式:是通過濾鏡裝飾了照片。在不改變對象(照片)的情況下動態(tài)的為其添加功能(濾鏡)。
        推薦度:
        導讀新手快速入門JavaScript裝飾者模式與AOP:什么是裝飾者模式 當我們拍了一張照片準備發(fā)朋友圈時,許多小伙伴會選擇給照片加上濾鏡。同一張照片、不同的濾鏡組合起來就會有不同的體驗。這里實際上就應用了裝飾者模式:是通過濾鏡裝飾了照片。在不改變對象(照片)的情況下動態(tài)的為其添加功能(濾鏡)。

        什么是裝飾者模式

        當我們拍了一張照片準備發(fā)朋友圈時,許多小伙伴會選擇給照片加上濾鏡。同一張照片、不同的濾鏡組合起來就會有不同的體驗。這里實際上就應用了裝飾者模式:是通過濾鏡裝飾了照片。在不改變對象(照片)的情況下動態(tài)的為其添加功能(濾鏡)。

        需要注意的是:由于 JavaScript 語言動態(tài)的特性,我們很容易就能改變某個對象(JavaScript 中函數(shù)是一等公民)。但是我們要盡量避免直接改寫某個函數(shù),這會導致代碼的可維護性、可擴展性變差,甚至會污染其他業(yè)務。

        什么是 AOP

        想必大家對"餐前洗手、飯后漱口"都不陌生。這句標語其實就是 AOP 在生活中的例子:吃飯這個動作相當于切點,我們可以在這個切點前、后插入其它如洗手等動作。

        AOP(Aspect-Oriented Programming):面向切面編程,是對 OOP 的補充。利用AOP可以對業(yè)務邏輯的各個部分進行隔離,也可以隔離業(yè)務無關(guān)的功能比如日志上報、異常處理等,從而使得業(yè)務邏輯各部分之間的耦合度降低,提高業(yè)務無關(guān)的功能的復用性,也就提高了開發(fā)的效率。

        在 JavaScript 中,我們可以通過裝飾者模式來實現(xiàn) AOP,但是兩者并不是一個維度的概念。 AOP 是一種編程范式,而裝飾者是一種設(shè)計模式。

        ES3 下裝飾者的實現(xiàn)

        了解了裝飾者模式和 AOP 的概念之后,我們寫一段能夠兼容 ES3 的代碼來實現(xiàn)裝飾者模式:

        // 原函數(shù)
        var takePhoto =function(){
        console.log('拍照片');
        }
        // 定義 aop 函數(shù)
        var after=function( fn, afterfn ){ 
        return function(){
        let res = fn.apply( this, arguments ); 
        afterfn.apply( this, arguments );
        return res;
        }
        }
        // 裝飾函數(shù)
        var addFilter=function(){
        console.log('加濾鏡');
        }
        // 用裝飾函數(shù)裝飾原函數(shù)
        takePhoto=after(takePhoto,addFilter);
        takePhoto();

        這樣我們就實現(xiàn)了抽離拍照與濾鏡邏輯,如果以后需要自動上傳功能,也可以通過aop函數(shù)after來添加。

        ES5 下裝飾者的實現(xiàn)

        在 ES5 中引入了Object.defineProperty,我們可以更方便的給對象添加屬性:

        let takePhoto = function () {
        console.log('拍照片');
        }
        // 給 takePhoto 添加屬性 after
        Object.defineProperty(takePhoto, 'after', {
        writable: true,
        value: function () {
        console.log('加濾鏡');
        },
        });
        // 給 takePhoto 添加屬性 before
        Object.defineProperty(takePhoto, 'before', {
        writable: true,
        value: function () {
        console.log('打開相機');
        },
        });
        // 包裝方法
        let aop = function (fn) {
        return function () {
        fn.before()
        fn()
        fn.after()
        }
        }
        takePhoto = aop(takePhoto)
        takePhoto()

        基于原型鏈和類的裝飾者實現(xiàn)

        我們知道,在 JavaScript 中,函數(shù)也好,類也好都有著自己的原型,通過原型鏈我們也能夠很方便的動態(tài)擴展,以下是基于原型鏈的寫法:

        class Test {
        takePhoto() {
        console.log('拍照');
        }
        }
        // after AOP
        function after(target, action, fn) {
        let old = target.prototype[action];
        if (old) {
        target.prototype[action] = function () {
        let self = this;
        fn.bind(self);
        fn(handle);
        }
        }
        }
        // 用 AOP 函數(shù)修飾原函數(shù)
        after(Test, 'takePhoto', () => {
        console.log('添加濾鏡');
        });
        let t = new Test();
        t.takePhoto();

        使用 ES7 修飾器實現(xiàn)裝飾者

        在 ES7 中引入了@decorator 修飾器的提案,參考阮一峰的文章。修飾器是一個函數(shù),用來修改類的行為。目前Babel轉(zhuǎn)碼器已經(jīng)支持。注意修飾器只能裝飾類或者類屬性、方法。三者的具體區(qū)別請參考 MDN Object.defineProperty ;而 TypeScript 的實現(xiàn)又有所不同:TypeScript Decorator。

        接下來我們通過修飾器來實現(xiàn)對方法的裝飾:

        function after(target, key, desc) {
        const { value } = desc;
        desc.value = function (...args) {
        let res = value.apply(this, args);
        console.log('加濾鏡')
        return res;
        }
        return desc;
        }
        class Test{
        @after
        takePhoto(){
        console.log('拍照')
        }
        }
        let t = new Test()
        t.takePhoto()

        可以看到,使用修飾器的代碼非常簡潔明了。

        場景:性能上報

        裝飾者模式可以應用在很多場景,典型的場景是記錄某異步請求請求耗時的性能數(shù)據(jù)并上報:

        function report(target, key, desc) {
        const { value } = desc;
        desc.value = async function (...args) {
        let start = Date.now();
        let res = await value.apply(this, args);
        let millis = Date.now()-start;
        // 上報代碼
        return res;
        }
        return desc;
        }
        class Test{
        @report
        getData(url){
        // fetch 代碼
        }
        }
        let t = new Test()
        t.getData()

        這樣使用@report修飾后的代碼就會上報請求所消耗的時間。擴展或者修改report函數(shù)不會影響業(yè)務代碼,反之亦然。

        場景:異常處理

        我們可以對原有代碼進行簡單的異常處理,而無需侵入式的修改:

        function handleError(target, key, desc) {
        const { value } = desc;
        desc.value = async function (...args) {
        let res;
        try{
        res = await value.apply(this, args);
        }catch(err){
        // 異常處理
        logger.error(err)
        }
        return res;
        }
        return desc;
        }
        class Test{
        @handleError
        getData(url){
        // fetch 代碼
        }
        }
        let t = new Test()
        t.getData()

        通過以上兩個示例我們可以看到,修飾器的定義很簡單,功能卻非常強大。

        小結(jié)

        我們一步一步通過高階函數(shù)、原型鏈、Object.defineProperty和@Decorator分別實現(xiàn)了裝飾者模式。接下來在回顧一下:

      1. 裝飾者模式非常適合給業(yè)務代碼附加非業(yè)務相關(guān)功能(如日志上報),就如同給照片加濾鏡;
      2. 裝飾者模式非常適合無痛擴展別人的代碼(你經(jīng)常需要接手別人的項目吧)
      3. 有些朋友可能會覺得裝飾者模式和 vue 的 mixin 機制很像,其實他們都是“開放-封閉原則”和“單一職責原則”的體現(xiàn)。

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        新手快速入門JavaScript裝飾者模式與AOP

        新手快速入門JavaScript裝飾者模式與AOP:什么是裝飾者模式 當我們拍了一張照片準備發(fā)朋友圈時,許多小伙伴會選擇給照片加上濾鏡。同一張照片、不同的濾鏡組合起來就會有不同的體驗。這里實際上就應用了裝飾者模式:是通過濾鏡裝飾了照片。在不改變對象(照片)的情況下動態(tài)的為其添加功能(濾鏡)。
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲无线一二三四区手机| 免费一级毛片正在播放| 99视频在线免费| **aaaaa毛片免费| 女人18毛片水真多免费看| 亚洲人妻av伦理| 精品久久久久久国产免费了 | 国产zzjjzzjj视频全免费| 久久国产亚洲精品麻豆| 亚洲中文无码线在线观看| 亚洲日韩精品一区二区三区 | 久久精品国产亚洲AV果冻传媒| 亚洲欧洲日韩极速播放| a视频在线观看免费| 美女黄网站人色视频免费国产| 日韩亚洲一区二区三区| 日本免费一区二区久久人人澡| 免费黄色app网站| 免费观看又污又黄在线观看| 一区二区三区四区免费视频 | 国产成人午夜精品免费视频| 中文字幕亚洲不卡在线亚瑟| 丰满亚洲大尺度无码无码专线| 免费A级毛片在线播放| 2020久久精品亚洲热综合一本| 午夜爽爽爽男女免费观看影院| 亚洲国产高清美女在线观看 | 亚洲国产成人无码AV在线| 好久久免费视频高清| 国内精品久久久久久久亚洲| 蜜臀亚洲AV无码精品国产午夜.| 亚洲精品tv久久久久久久久久| 亚洲三级视频在线| 免费在线观看毛片| 免费一区二区三区| 久久久久亚洲国产| 亚洲日韩av无码| 日本高清色本免费现在观看| 最新亚洲卡一卡二卡三新区| 亚洲天堂中文字幕在线| 2021久久精品免费观看|