segmentfault官方|为 Express 开外挂( 三 )


elsefor(var i = decorators.length - 1; i >= 0; i--) if(d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
returnc > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = http://news.hoteastday.com/a/(this && this.__metadata) || function(k, v) {
if(typeof Reflect === "object"&& typeof Reflect.metadata =http://news.hoteastday.com/a/=="function") returnReflect.metadata(k, v);
};
functionMyDecorators(target) {
target.prototype.say = function{
console.log( "Hello 前端自习课!");
};
}
letLeoClass = class LeoClass {
constructor{ }
say{ console.log( "Hello Leo"); }
};
LeoClass = __decorate([
MyDecorators,
__metadata( "design:paramtypes", [])
], LeoClass);
letleo = new LeoClass;
leo.say;
// 'Hello Leo!';
其实就是 __decorate 函数啦 , 具体大家可以自行细看咯~
从编译后 JS 代码中可以看出 , 装饰器是在模块导入时便执行的 。 如下:
LeoClass = __decorate([
MyDecorators,
__metadata( "design:paramtypes", [])
], LeoClass);
1.5 小结
接下来通过下图来回顾装饰器的知识 。
segmentfault官方|为 Express 开外挂
本文插图

2. Reflect Metadata API
2.1 什么是 Reflect ?
Reflect(即反射)是 ES6 新增的一个内置对象 , 它提供用来拦截和操作 Java 对象的 API 。 并且 Reflect 的所有属性和方法都是静态的 , 就像 Math 对象( Math.random 等) 。
更多 Reflect 详细介绍 , 请阅读文档《MDN Reflect》:
https://developer.mozilla.org/zh-CN/docs/Web/Java/Reference/Global_Objects/Reflect 。
2.2 为什么出现 Reflect?
其核心目的 , 是为了保持 JS 的简单 , 让我们可以不用写很多代码 , 这里举个栗子?? , 看看有使用 Reflect 和没使用有什么区别:
当对象里有 Symbol 时 , 如何遍历对象的 keys?
const s = Symbol( 'foo');
const k = 'bar';
const o = { [s]: 1, [k]: 1 };
// 没有使用 Reflect
const keys = Object.getOwnPropertyNames(o).concat(Object.getOwnPropertySymbols(o));
// 使用 Reflect
Reflect.ownKeys(o);
这看起来是不是简单多了?
更多 Reflect 详细介绍 , 请阅读文档《MDN Reflect》 。
2.3 什么是 Reflect Metadata
Reflect Metadata 是 ES7 的一个提案 , 它主要用来在声明的时添加和读取元数据 。 Type 在 1.5+ 的版本已经支持它 , 你只需要:

  • npm i reflect-metadata --save 。
  • 在 tsconfig.json 里配置 emitDecoratorMetadata 选项 。
Reflect Metadata 可以当做装饰器使用 , 有两个 API:
  • 使用 Reflect.metadata API 添加元数据;
  • 使用 Reflect.getMetadata API 读取元数据 。
@Reflect.metadata( 'inClass', 'A')
class LearnReflect {
@Reflect.metadata( 'inMethod', 'B')
public hello: string {
return'hello world';
}
}
console.log(Reflect.getMetadata( 'inClass', LearnReflect)); // 'A'
console.log(Reflect.getMetadata( 'inMethod', new LearnReflect, 'hello')); // 'B'


推荐阅读