前置知识
Reflect API
官方文档:reflect-metadata
举个例子介绍常用的 API:
@Reflect.metadata('key', 'value')
class Person {
name: string;
constructor(public age: number) {
}
}
Reflect.getMetadata('design:type', Person.prototype, 'name');
// 作用:获取元数据键对应的元数据值,design:type表示参数类型
// 输出: [Function: String]
// 参数:(元数据键, 类构造函数/对象, 属性名【可选】)
Reflect.defineMetadata('custom:tag', 'VIP', Person.prototype, 'name');
console.log(Reflect.getMetadata('custom:tag', Person.prototype, 'name'));
// 作用:定义元数据键对应的元数据值
// 输出: VIP
// 参数:(元数据键, 值, 类构造函数/对象, 属性名【可选】)
Reflect.getOwnMetadataKeys(Person.prototype, 'name');
// 作用:获取元数据键
// 输出: ['design:type', 'custom:tag']
// 参数:(类构造函数/对象, 属性名【可选】)
装饰器
类装饰器
//添加日志打印
function Log(){
return function (target) {
return class extends target {
constructor(...args) {
console.log('log')
super(...args)
}
}
}
}
//修改构造函数,实现单例模式
function Singleton() {
return function (target) {
return class extends target {
private static instance: any;
constructor(...args: any[]) {
if (Singleton.instance) {
return Singleton.instance;
}
super(...args);
Singleton.instance = this;
}
};
};
}
@Log()
@Singleton()
class Database {
constructor(private connectionString: string) {
}
}
const db1 = new Database("db://localhost"); // 打印log
const db2 = new Database("db://localhost/another"); // 打印log
console.log(db1 === db2); // true
方法装饰器
// 权限验证装饰器
function Authenticated() {
// 参数:target: 类的原型,propertyKey: 方法名,descriptor: 方法描述符,包含get/set/value/writable/configurable等属性
return function (target, propertyKey, descriptor) {
const originalMethod =