摘要:在的中,定義了種不同裝飾器的接口,其中裝飾類以及裝飾類方法的接口定義如下所示下面對(duì)這兩種情況進(jìn)行解析。作用于類的裝飾器當(dāng)裝飾的對(duì)象是類時(shí),我們操作的就是這個(gè)類本身。相關(guān)鏈接中的裝飾器裝飾器場(chǎng)景實(shí)戰(zhàn)修飾器
隨著 ES6 和 TypeScript 中類的引入,在某些場(chǎng)景需要在不改變?cè)蓄惡皖悓傩缘幕A(chǔ)上擴(kuò)展些功能,這也是裝飾器出現(xiàn)的原因。
裝飾器簡(jiǎn)介作為一種可以動(dòng)態(tài)增刪功能模塊的模式(比如 redux 的中間件機(jī)制),裝飾器同樣具有很強(qiáng)的動(dòng)態(tài)靈活性,只需在類或類屬性之前加上 @方法名 就完成了相應(yīng)的類或類方法功能的變化。
不過裝飾器模式仍處于第 2 階段提案中,使用它之前需要使用 babel 模塊 transform-decorators-legacy 編譯成 ES5 或 ES6。
在 TypeScript 的 lib.es5.d.ts 中,定義了 4 種不同裝飾器的接口,其中裝飾類以及裝飾類方法的接口定義如下所示:
declare type ClassDecorator =(target: TFunction) => TFunction | void; declare type MethodDecorator = (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor ) => TypedPropertyDescriptor | void;
下面對(duì)這兩種情況進(jìn)行解析。
作用于類的裝飾器當(dāng)裝飾的對(duì)象是類時(shí),我們操作的就是這個(gè)類本身。
@log class MyClass { } function log(target) { // 這個(gè) target 在這里就是 MyClass 這個(gè)類 target.prototype.logger = () => `${target.name} 被調(diào)用` } const test = new MyClass() test.logger() // MyClass 被調(diào)用
由于裝飾器是表達(dá)式,我們也可以在裝飾器后面再添加提個(gè)參數(shù):
@log("hi") class MyClass { } function log(text) { return function(target) { target.prototype.logger = () => `${text},${target.name} 被調(diào)用` } } const test = new MyClass() test.logger() // hello,MyClass 被調(diào)用
在使用 redux 中,我們最常使用 react-redux 的寫法如下:
@connect(mapStateToProps, mapDispatchToProps) export default class MyComponent extends React.Component {}
經(jīng)過上述分析,我們知道了上述寫法等價(jià)于下面這種寫法:
class MyComponent extends React.Component {} export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)作用于類方法的裝飾器
與裝飾類不同,對(duì)類方法的裝飾本質(zhì)是操作其描述符??梢园汛藭r(shí)的裝飾器理解成是 Object.defineProperty(obj, prop, descriptor) 的語法糖,看如下代碼:
class C { @readonly(false) method() { console.log("cat") } } function readonly(value) { return function (target, key, descriptor) { // 此處 target 為 C.prototype; key 為 method; // 原 descriptor 為:{ value: f, enumarable: false, writable: true, configurable: true } descriptor.writable = value return descriptor } } const c = new C() c.method = () => console.log("dog") c.method() // cat
可以看到裝飾器函數(shù)接收的三個(gè)參數(shù)與 Object.defineProperty 是完全一樣的,具體實(shí)現(xiàn)可以看 babel 轉(zhuǎn)化后的代碼,主要實(shí)現(xiàn)如下所示:
var C = (function() { class C { method() { console.log("cat") } } var temp temp = readonly(false)(C.prototype, "method", temp = Object.getOwnPropertyDescriptor(C.prototype, "method")) || temp // 通過 Object.getOwnPropertyDescriptor 獲取到描述符傳入到裝飾器函數(shù)中 if (temp) Object.defineProperty(C.prototype, "method", temp) return C })()
再將再來看看如果有多個(gè)裝飾器作用于同一個(gè)方法上呢?
class C { @readonly(false) @log method() { } }
經(jīng) babel 轉(zhuǎn)化后的代碼如下:
desc = [readonly(false), log] .slice() .reverse() .reduce(function(desc, decorator) { return decorator(target, property, desc) || desc; }, desc);
可以清晰地看出,經(jīng)過 reverse 倒序后,裝飾器方法會(huì)至里向外執(zhí)行。
相關(guān)鏈接javascript-decorators
Javascript 中的裝飾器
JS 裝飾器(Decorator)場(chǎng)景實(shí)戰(zhàn)
修飾器
Babel
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/93493.html
摘要:本套課程包含兩大部分,第一部分是基礎(chǔ)部分,也是重要部分,參考官方文檔結(jié)構(gòu),針對(duì)內(nèi)容之間的關(guān)聯(lián)性和前后順序進(jìn)行合理調(diào)整。 showImg(https://segmentfault.com/img/bVbpBA0?w=1460&h=400); 講師簡(jiǎn)介: iview 核心開發(fā)者,iview-admin 作者,百萬級(jí)虛擬渲染表格組件 vue-bigdata-table 作者。目前就職于知名互...
摘要:第二部分源碼解析接下是應(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...
摘要:歷史裝飾器這個(gè)概念三年多前被首次提出。在版本年中發(fā)布了對(duì)裝飾器的支持以及許多特性。有不同的安全級(jí)別需要考慮裝飾器不應(yīng)該意外泄漏私有名稱。你可以測(cè)試裝飾器的新語法,并向提案的作者們提出反饋意見。 原文地址:https://babeljs.io/blog/2018/...原文作者:Nicolò Ribaudo Babel 7.1.0最終支持新的裝飾器提案,可以通過@babel/plugin...
摘要:裝飾器我們?yōu)樯兑懻撛刈⑷肫鞫皇茄b飾器這是因?yàn)闀?huì)把元素注入器依賴解析過程限制在當(dāng)前組件視圖內(nèi)。但是一旦使用了裝飾器,整個(gè)依賴解析過程就會(huì)在第一階段完成后停止解析,也就是說,元素注入器只在組件視圖內(nèi)解析依賴,然后就停止解析工作。 原文鏈接:A curious case of the @Host decorator and Element Injectors in Angular 我...
摘要:所以這是一篇插隊(duì)的文章,用于去理解中的裝飾器和概念。因此,該的作用就是根據(jù)入?yún)⒎祷鼐唧w的描述符。其次局部來看,裝飾器具體應(yīng)用表達(dá)式是,其函數(shù)簽名和是一模一樣。等裝飾器語法,是和直接使用是等效等價(jià)的。 ================前言=================== 初衷:以系列故事的方式展現(xiàn) MobX 源碼邏輯,盡可能以易懂的方式講解源碼; 本系列文章: 《【用故事解...
閱讀 2044·2021-11-22 09:34
閱讀 3375·2021-09-28 09:35
閱讀 13922·2021-09-09 11:34
閱讀 3695·2019-08-29 16:25
閱讀 2898·2019-08-29 15:23
閱讀 2102·2019-08-28 17:55
閱讀 2497·2019-08-26 17:04
閱讀 3099·2019-08-26 12:21