typeScript-装饰器
目录
typeScript 装饰器
TypeScript装饰器
要使用装饰器,需要在tsconfig.json中启用experimentalDecorators选项:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
1、类装饰器
可以给类添加属性、方法, 或者重写类的方法
返回值(可选): 如果类装饰器有返回值,就会替换掉原来的构造方法
function classDecorator(contructor: any) {
contructor.property.newName = "新增的属性";
const originNormalFunc = contructor.property.normalFunc;
contructor.property.normalFunc = function () {
if(originNormalFunc) {
originNormalFunc.call(this);
}
//todo 这里可以添加附加的逻辑
console.log("附加逻辑");
return constructor;
}
}
@classDecorator
class MyClass {
name: string;
constructor(name: string) {
this.name = name;
console.log('MyClass 实例化');
}
normalFunc() {
consloe.log("normalFunc");
}
}
2、方法装饰器
func(target: any, objectKey: string, decriptor: PropertyDescriptor)
target:方法所属的类的原型对象(对于静态方法是类的构造函数)
普通方法通过target.constructor.name获取类名
静态方法通过target.name获取类名
propertyKey:方法名
descriptor:方法的属性描述符(PropertyDescriptor)
descriptor是一个PropertyDescriptor对象,包含以下属性
interface PropertyDescriptor { value?: any; // 值(此处为函数本身) writable?: boolean; // 是否可写 enumerable?: boolean; // 是否可枚举 configurable?: boolean; // 是否可配置 get?(): any; // getter 函数 set?(v: any): void; // setter 函数 }
function funcDecorator (target: any, objectKey: string, descriptor: PropertyDescriptor) {
const originFunc = descriptor.value;
decriptor.value = function(...args: any[]) {
const result = originFunc.aplay(this, args);
//todo 重新逻辑
console.log("重写逻辑");
return result;
}
return decriptor;
}
class Calculator {
@funcDecorator
add(a: number, b: number): number {
return a + b;
}
}
3、属性装饰器
propertyDecorator(garget: any, objectKey: string)
target:类的原型对象(对于静态成员是类的构造函数)
propertyKey:属性名
function TestPropoerty(target: Object, propertyKey: string) {
console.log(`对象: ${target.constructor.name}的属性: ${propertyKey}被装饰`);
}
function LogProperty(target: Object, propertyKey: string) {
const propDesc = Object.getOwnPropertyDescriptor(target, propertyKey);
console.log(`属性: ${propertyKey} ${propDesc}`);
}
class User {
@TestPropoerty
@LogProperty
name: string = "A";
}