国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題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關鍵字專題關鍵字專題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
當前位置: 首頁 - 科技 - 知識百科 - 正文

詳解ES7 Decorator 入門解析

來源:懂視網 責編:小采 時間:2020-11-27 22:00:50
文檔

詳解ES7 Decorator 入門解析

詳解ES7 Decorator 入門解析:Decorator 提供了一種獨特的抽象邏輯,可在原有代碼基礎上,零侵入添加新功能特性。商業代碼總是多種交織并存的,在日常開發中,除了實現業務功能之外,我們還需要考慮諸如:異常處理、性能分析、日志等額外的需求。未經設計的的開發方法會傾向于將各種需求耦
推薦度:
導讀詳解ES7 Decorator 入門解析:Decorator 提供了一種獨特的抽象邏輯,可在原有代碼基礎上,零侵入添加新功能特性。商業代碼總是多種交織并存的,在日常開發中,除了實現業務功能之外,我們還需要考慮諸如:異常處理、性能分析、日志等額外的需求。未經設計的的開發方法會傾向于將各種需求耦

Decorator 提供了一種獨特的抽象邏輯,可在原有代碼基礎上,零侵入添加新功能特性。商業代碼總是多種交織并存的,在日常開發中,除了實現業務功能之外,我們還需要考慮諸如:異常處理、性能分析、日志等額外的需求。未經設計的的開發方法會傾向于將各種需求耦合組成一個功能模塊,比如:

class Math{
 static add(num1,num2){
 try{
 console.time('some label');
 log('log for something');
 const result= num1+num2;
 console.timeEnd('some label');
 return result;
 }catch(e){
 error('something had broken');
 }
 }
}

上述簡單的兩數相加功能,在添加各類需求之后,已經變的面目全非。Decorator 語法通過描述,可將功能特性疊加到原有功能中:

class Math{
 @log
 @error
 @time
 static add(num1,num2){
 return num1+num2;
 }
}

Decorator 是什么

Decorator 就是一個的包裹函數,運行時在編譯階段調用該函數,修改目標對象的行為、屬性。我們先來看一個簡單實例:

const log = (target,prop)=>console.log(`Wrap function: '${prop}'`);

const tec={
 @log
 say(){
 console.log('hello world')
 }
}

// => Wrap function 'say'

Decorator 函數簽名如下:

// @param target 作用對象
// @param prop 作用的屬性名
// @param descriptor 屬性描述符
// @return descriptor 屬性描述符
function decorator(target,prop,descriptor){}

參數詳解:

  • target : 作用的對象,有如下情況:
  • 作用于 class 時,target 為該 class 函數
  • 作用于 class 中的函數、屬性 時,target 為該 class 的 prototype 對象
  • 作用于 對象字面量中的函數、屬性 時,target 為該對象
  • prop : 描述的屬性名,若decorator作用于class時,該參數為空
  • descriptor : 屬性原本的描述符,該描述符可通過Object.getOwnPropertyDescriptor() 獲取,若decorator作用于class時,該參數為空
  • decorator 函數支持返回描述符或 undefined,當返回值為描述符時,運行時會調用Object.defineProperty()修改原有屬性。
  • Decorator 的ES5實現

    理解 Decorator 機制,最佳方式是使用ES5實現該過程。

    class裝飾器機制比較簡單,僅做一層包裝,偽代碼:

    // 調用實例
    @log 
    class Person{}
    // 實現代碼
    const Person = log(Person);
    

    屬性裝飾器機制則比較復雜,babel 就此提供了一個參考范例:

    // decorator 處理
    function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
     var desc = {};
     Object['ke' + 'ys'](descriptor).forEach(function (key) {
     desc[key] = descriptor[key];
     });
     desc.enumerable = !!desc.enumerable;
     desc.configurable = !!desc.configurable;
    
     if ('value' in desc || desc.initializer) {
     desc.writable = true;
     }
    
     desc = decorators.slice().reverse().reduce(function (desc, decorator) {
     return decorator(target, property, desc) || desc;
     }, desc);
    
     if (context && desc.initializer !== void 0) {
     desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
     desc.initializer = undefined;
     }
    
     if (desc.initializer === void 0) {
     Object['define' + 'Property'](target, property, desc);
     desc = null;
     }
    
     return desc;
    }
    
    // 調用實例
    class Person{
     @log
     say(){}
    }
    
    // 實現代碼
    _applyDecoratedDescriptor(
     Person.prototype, 
     'say', 
     [log],
     Object.getOwnPropertyDescriptor(Person.prototype, 'say'),
     Person.prototype)
    )

    用例

    Decorator 主要應用于如下幾類對象:

    1. class
    2. class 中,除構造函數外的方法
    3. class 中的屬性
    4. 對象字面量中的函數
    5. 對象字面量中的屬性
    // 類
    @log
    class Person{
     // 函數
     @log
     say(){}
     
     // 屬性
     @log
     name = 'tec';
    }
    
    // 同樣適用于對象字面量的方法、屬性
    const tec = {
     @log
     name:'tec',
     
     @log
     walk(){}
    };

    Decorator 實踐

    在JS中,Decorator 是一個新概念,對于多數沒有接觸過諸如python、C#的開發者而言,很難理解實際應用場景。幸運的是github已經有人封裝了常用Decorator。筆者分析該庫,總結如下幾種定義模式:

    通過 descriptor 的 value 值修改:

    function decorate(target, key, descriptor) {
     const fn = descriptor.value;
    
     return {
     ...descriptor,
     value() {
     return fn.apply(this, arguments);
     }
     }
    }
    
    

    通過 descriptor 的 get、set 函數修改:

    function decorate(target, key, descriptor) {
     let value = descriptor.value;
    
     return {
     ...descriptor,
     get() {
     return value;
     }
     set(v) {
     value=v;
     }
     }
    }
    
    

    通過 descriptor 的 writable、enumerable 等屬性修改:

    function readonly(target, key, descriptor) {
     return {
     ...descriptor,
     writable:false
     }
    }
    

    針對 class ,返回包裹函數

    function log(target){
     let initTimes=0;
     return (...arg)=>{
     console.log(++initTimes);
     target.call(this,...arg);
     };
    }
    

    在實際開發中,還需要注意以下事項:

  • Decorator 的目標是在原有功能基礎上,添加功能,切忌覆蓋原有功能
  • Decorator 不是管道模式,decorator之間不存在交互,所以必須注意保持decorator獨立性、透明性
  • Decorator 更適用于非業務功能需求
  • 確定 decorator 的用途后,切記執行判斷參數類型
  • decorator 針對每個裝飾目標,僅執行一次
  • 聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    詳解ES7 Decorator 入門解析

    詳解ES7 Decorator 入門解析:Decorator 提供了一種獨特的抽象邏輯,可在原有代碼基礎上,零侵入添加新功能特性。商業代碼總是多種交織并存的,在日常開發中,除了實現業務功能之外,我們還需要考慮諸如:異常處理、性能分析、日志等額外的需求。未經設計的的開發方法會傾向于將各種需求耦
    推薦度:
    標簽: 入門 decorator es7
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 久久精品国产亚洲aa | 麻豆91精品91久久久 | 一区二区网站 | 中文字幕日韩有码 | 亚洲自拍另类 | 在线欧美日韩精品一区二区 | 欧美αv日韩αv另类综合 | 日韩精品一区二区三区毛片 | 亚洲日本一区二区三区 | 亚洲欧美在线免费观看 | 国产最新在线视频 | 国产精品特级毛片一区二区三区 | 久久久精品久久久久久久久久久 | 日韩中文欧美 | 久久久久久久亚洲精品 | 亚洲欧美日韩高清综合678 | 国产全黄a一级毛片视频 | 国产成人精品999在线观看 | 91久久精品| 欧美精品首页 | 91区国产| a国产成人免费视频 | 欧美日比 | 日韩欧美网 | 国产一区欧美二区 | 成人免费久久精品国产片久久影院 | 欧美性一区二区三区五区 | 欧美日韩免费电影 | 亚洲一区日韩 | 国产综合成人久久大片91 | 精品成人一区二区三区免费视频 | 亚洲国产成人精品一区91 | 久久精品一级 | 一级大毛片 | 91原创国产| 亚洲精品国产成人7777 | 国内一区亚洲综合图区欧美 | 精品在线免费观看 | 欧美亚洲精品在线 | 欧美亚洲韩国 | 国内精品视频一区二区三区 |