摘要:裝飾器顧名思義就是裝飾某種東西的方法,可以用來裝飾屬性變量函數類實例方法本質上是個函數。以符開頭,函數名稱自擬。愛吃蘋果裝飾器裝飾類愛吃蘋果結果是這個類本身就可以通過修改類的屬性增加屬性被裝飾的對象可以使用多個裝飾器。
@Decorator 裝飾器是es7的語法,這個方法對于面向切面編程有了更好的詮釋,在一些情境中可以使用,比如路人A的代碼實現了一需求,路人B希望用A的方法來實現一個新的需求,而路人A又不希望大改自己的代碼,這時候裝飾器就能派上用場了。本文就結合情境來說說Decorator的用法。
裝飾器顧名思義就是裝飾某種東西的方法,可以用來裝飾屬性、變量、函數、類、實例方法... 本質上是個函數。以@符開頭,函數名稱自擬。
先看這么一個類↓
@hobby Class Person { constructor() { } @readOnly name = "AAA"; @dealData eat() { console.log("愛吃蘋果") } } let oP = new Person(); 這個函數就用來修飾裝飾對象的 function readOnly(proto, key, descriptor) { console.log(proto, key, descriptor) //原型, "name ", 一個包含對name屬性描述內容的對象 } descriptor是重頭戲,這個對象里包含對裝飾對象的描述屬性 configurable: true/false, 可配置與否 enumerable: true/false, 可枚舉與否 writable: true/false, 可寫與否 initializer: 靜態屬性的value值 value: 非靜態屬性的value值 上面三個屬性好理解,修改也方便,如下 function readOnly(proto, key, descriptor) { // 將靜態屬性name改為只可讀,不可寫 descriptor.writable = false; }
initializer: 靜態屬性的value值
value: 非靜態屬性的value值
這兩個值就比較有意思了,他們倆的關系是水火不容的,靜態屬性的裝飾器的descriptor里有initializer, 而非靜態屬性的裝飾器其descriptor對象里則是有value這個屬性,沒有initializer。
function readOnly(proto, key, descriptor) { // initializer可以重新賦值 descriptor.initializer = function () { // 函數返回的值就是該靜態屬性新的值 return "BBB" } } function dealData(proto, key, descriptor) { // 當我們需要改變函數功能的時候,可以通過這種方式,相當于做個代理,也不會影響原函數 // 存一下原來的方法 let oldValue = descriptor.value; // 修改(添加)函數的原有功能 descriptor.value = function() { console.log("愛吃橘子"); oldValue.call(this, arguments); } } 裝飾器也是可以傳參并且執行返回的函數的 Class Person { constructor() { } @readOnly name = "AAA"; @dealData("AAA") eat() { console.log("愛吃蘋果") } } function dealData(who) { return function (proto, key, descriptor) { let oldValue = descriptor.value; descriptor.value = function() { console.log(who + "愛吃橘子"); // AAA愛吃橘子 return oldValue.call(this, arguments); } } }
值得注意的一點是如果這里的eat函數寫成箭頭函數賦值的形式,就不再是原型上的方法了而是變為靜態屬性了,要注意一下。
Class Person { constructor() { } @readOnly name = "AAA"; @dealData("AAA") eat = ()=> { console.log("愛吃蘋果") } }
裝飾器裝飾類:
@hobby Class Person { constructor() { } @readOnly name = "AAA"; @dealData eat() { console.log("愛吃蘋果") } } function hobby(target) { console.log(target) // 結果是這個類本身 // 就可以通過target修改類的屬性 target.name = "CCC"; // 增加屬性 target.age = 18; }
被裝飾的對象可以使用多個裝飾器。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106599.html
摘要:原文博客地址裝飾器模式為對象添加新功能不改變其原有的結構和功能。手機殼就是裝飾器,沒有它手機也能正常使用,原有的功能不變,手機殼可以減輕手機滑落的損耗。 原文博客地址:https://finget.github.io/2018/11/22/decorator/ 裝飾器模式 為對象添加新功能;不改變其原有的結構和功能。 手機殼就是裝飾器,沒有它手機也能正常使用,原有的功能不變,手機殼可以...
摘要:相關設計模式裝飾者模式和代理模式裝飾者模式關注再一個對象上動態添加方法代理模式關注再對代理對象的控制訪問,可以對客戶隱藏被代理類的信息裝飾著模式和適配器模式都叫包裝模式關于新職責適配器也可以在轉換時增加新的職責,但主要目的不在此。 0x01.定義與類型 定義:裝飾模式指的是在不必改變原類文件和使用繼承的情況下,動態地擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的...
摘要:作者按每天一個設計模式旨在初步領會設計模式的精髓,目前采用和兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式原文地址是每天一個設計模式之裝飾者模式歡迎關注個人技術博客。 作者按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前采用javascript和python兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式...
摘要:作者按每天一個設計模式旨在初步領會設計模式的精髓,目前采用和兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式原文地址是每天一個設計模式之裝飾者模式歡迎關注個人技術博客。 作者按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前采用javascript和python兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式...
摘要:第二部分源碼解析接下是應用多個第二部分對于一個方法應用了多個,比如會編譯為在第二部分的源碼中,執行了和操作,由此我們也可以發現,如果同一個方法有多個裝飾器,會由內向外執行。有了裝飾器,就可以改寫上面的代碼。 Decorator 裝飾器主要用于: 裝飾類 裝飾方法或屬性 裝飾類 @annotation class MyClass { } function annotation(ta...
閱讀 3391·2021-09-22 15:17
閱讀 2739·2021-09-02 15:15
閱讀 1748·2019-08-30 15:54
閱讀 2000·2019-08-30 14:02
閱讀 2529·2019-08-29 16:58
閱讀 2988·2019-08-29 16:08
閱讀 1330·2019-08-26 12:24
閱讀 1653·2019-08-26 10:41