使用 TypeScript 自定义装饰器给类的属性增添监听器 Listener
生活随笔
收集整理的這篇文章主要介紹了
使用 TypeScript 自定义装饰器给类的属性增添监听器 Listener
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
官網鏈接
語法
type PropertyDecorator =(target: Object, propertyKey: string | symbol) => void;target:直接寫在類的屬性上?
看個例子:
function capitalizeFirstLetter(str: string) {return str.charAt(0).toUpperCase() + str.slice(1); }function observable(target: any, key: string): any {// prop -> onPropChangeconst targetKey = "on" + capitalizeFirstLetter(key) + "Change";target[targetKey] =function (fn: (prev: any, next: any) => void) {let prev = this[key];Reflect.defineProperty(this, key, {set(next) {fn(prev, next);prev = next;}})}; }class C {@observablefoo = -1;@observablebar = "bar"; }const c = new C();c.onFooChange((prev, next) => console.log(`prev: ${prev}, next: ${next}`)) c.onBarChange((prev, next) => console.log(`prev: ${prev}, next: ${next}`))c.foo = 100; // -> prev: -1, next: 100 c.foo = -3.14; // -> prev: 100, next: -3.14 c.bar = "baz"; // -> prev: bar, next: baz c.bar = "sing"; // -> prev: baz, next: sing編譯通不過:
一種解決辦法是,添加下圖這種 dummy 方法,這種方法不推薦,因為缺乏靈活性:
另一種方法較通用,即為類添加通用的所謂的 index signature:
語法如下:
意思是類 C 可以擁有任意的屬性,且屬性名稱為 string
運行時,target 的類型為類 C 的構造函數:
key 為屬性名:
在下圖第 15 行代碼,直接給 C 的構造函數注入一個新的 on 監聽函數:
這個監聽函數的函數體,直到代碼44行 onXXX 被調用時才會被執行:
給 C 對象實例的 foo 屬性使用 Reflect.defineProperty API 設置一個 set 方法。
這樣,每次該實例的 foo 屬性被修改時,就觸發其 set 函數:
在 set 函數實現體內,首先調用應用開發人員傳入的 回調函數 fn,然后將 this[key] 設置為新的值 next.
運行時,c.foo = 100, 會導致 Reflect.defineProperty 注冊在 foo 屬性的 set 方法被觸發:
在 set 函數里,我們再也不能訪問到 C 實例的 foo 或者 bar 屬性,但是通過閉包,能訪問到其修改之前的原始值:
更多Jerry的原創文章,盡在:“汪子熙”:
總結
以上是生活随笔為你收集整理的使用 TypeScript 自定义装饰器给类的属性增添监听器 Listener的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 有什么方法能速记单词 怎么能速记单词
- 下一篇: 2017广州大学录取分数线查询网站:广州