装饰器
装饰器是一个函数,然后使用@装饰器函数修饰被装饰对象,以达到不修改原始代码实现添加(修改)功能的目的。安装被修饰对象可以分为:
- 类装饰器:装饰类构造函数
- 属性装饰器:装饰类实例属性
- 函数装饰器:装饰类实例函数
- 参数装饰器:装饰类实例函数参数
类装饰器
ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction;
类装饰器通过操作类的构造函数,实现对类的属性和方法的修改,类装饰器只接受一个参数target即类本身的构造函数
function decoratorDemo(target) {
target.isDec = true;
}
@decoratorDemo
class Demo {}
console.log(Demo.idDec); // true
还可以结合高阶函数给装饰器传参
function decoratorDemo(idDec) {
return function (target) {
target.isDec = isDec;
};
}
@decoratorDemo(true)
class Demo {}
console.log(Demo.idDec); // true
函数装饰器
使用函数装饰器可以控制函数的输入输出,函数装饰器在class声明时执行,而不是在实例化时
MethodDecorator = <T>(target: Object, key: string, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | Void;
函数装饰器接收三个属性:
target:被装饰的对象key:被装饰的函数名descriptor:函数的属性描述符,可以通过Object.getOwnPropertyDescriptor()方法查看, 参考对象属性模型
函数装饰器的本质就是通过修改descriptor实现增强(装饰)效果
function InjectPrefix(prefix: string) {
return function(target, key, descriptor) {
const originFunc = descriptor.value
descriptor.value = function(...args) {
return originFunc(prefix + args[0])
}
return descriptor
}
}
class Demo {
@InjectPrefix('Mike-')
log(x) {
console.log(x)
}
}
const demo = new Demo()
demo.log('Jordan'); // Mike-Jordan
属性装饰器
属性装饰器和函数装饰器类似,可以重新定义getter、setter、enumerable、configurable等属性和方法。
PropertyDecorator = (target: Object, key: string) => void;
属性装饰器有两个参数:
target:属性拥有者,即类的实例key:属性名
class Prop {
@init(16)
age: number
}
function init(age: number) {
return function(target, key) {
target[key] = age
return target
}
}
const prop = new Prop();
console.log(prop.age)
参数装饰器
接收三个属性:
target:类实例key:参数名index:参数下标