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