當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
JS 中的装饰器
js 中的裝飾器還是一個提案,需要 babel 才可以使用。它還是一項實驗性特性,在未來的版本中可能會發生改變。
裝飾器是一個函數,它只能作用于類不能作用于(因為函數提升),它以一個@符號開頭,如下:
function d(target) { return target }@d class A {}// 它相當于把類作為參數傳遞給 d 函數,然后再返回一個被函數修改過的類 // 等同于 A = d(A) || A 復制代碼它還可以傳遞自定義參數和使用多個裝飾器
function a(p) {console.log(1)return (target => {console.log(2)return target}) } function b(target) {console.log(3)return target }@b @a(1) class A {}// 打印順序是 1 2 3 復制代碼多個裝飾器除了一行寫一個,也可以全都寫在一行@b @a(1)。
在 react-redux 應用中使用裝飾器可以這樣使用 connect 方法
@connect(mapStateToProps, mapDispatchToProps) export default class Comp extends Component {} 復制代碼方法的裝飾
裝飾器除了作用于類,還可以作用于類的方法。
function d(target, name, desc) {// target 是類的原型對象// name 是函數的名字// desc 是屬性描述符let oldValue = desc.value;desc.value = function() {console.log(`Calling ${name} with`, arguments);return oldValue.apply(this, arguments);};return desc// 如果方法裝飾器返回一個值,它會被用作方法的屬性描述符。 }class A {@dfn () {} } 復制代碼在 TypeScript 中方法裝飾器的 target 參數,對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象。
屬性裝飾器
在 TypeScript 中裝飾器還可以作用于屬性。
function d(target, name) {// target 對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象。// name 屬性的名字 }class A() {@dgreeting: string; } 復制代碼參數裝飾器
TypeScript 中還可以裝飾參數,
function Query(target, name, index) {// target 對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象// name 方法的函數名// index 參數的索引 從 0 開始// 參數裝飾器的返回值會被忽略。 }class A() {fn(@Query query: Object) {} } 復制代碼存取裝飾器
TypeScript 中裝飾器也可以裝飾存取聲明函數。
function d(target, name, desc) {// target 對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象// name 函數名// desc 屬性描述符return desc// 如果方法裝飾器返回一個值,它會被用作屬性描述符 }class A() {@dget a() {} } 復制代碼裝飾器求值
TypeScript 多個裝飾器執行順序是,
是從里到外的執行順序。
元數據
reflect-metadata 庫是來支持實驗性的metadata API,這個庫還不是ECMAScript (JavaScript)標準的一部分。
要使用元數據需要先開啟experimentalDecorators emitDecoratorMetadata選項。
當啟用后,只要reflect-metadata庫被引入了,設計階段添加的類型信息可以在運行時使用。
function D(...rest) {}class A {@Dreadonly a: string; }class B {fn(@D x: A) {console.log(x)} } 復制代碼會被轉義成
function D(...rest) { } class A { } __decorate([D,__metadata("design:type", String) ], A.prototype, "a", void 0); class B {fn(x) {console.log(x);} } __decorate([__param(0, D),__metadata("design:type", Function),__metadata("design:paramtypes", [A]),__metadata("design:returntype", void 0) ], B.prototype, "fn", null); 復制代碼它加入了__metadata函數,將裝飾器的元信息存取起來,這樣就可以隨時獲取出來。
nodejs 的 nestjs 框架就大量使用到了這些元信息。
轉載于:https://juejin.im/post/5c77f0f1518825629f387207
總結
- 上一篇: 【Laravel-海贼王系列】第十三章,
- 下一篇: JavaScript 复习之 事件模型