关于ts的安装和使用请看上一篇:TS编写和使用装饰器之(一):类装饰器
方法装饰器声明在一个方法的声明之前(紧靠着方法声明)。 它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。 方法装饰器不能用在声明文件( .d.ts
),重载或者任何外部上下文(比如declare
的类)中。
方法装饰器表达式会在运行时当作函数被调用,传入下列3个参数:
1.对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
2.成员的名字。
3.成员的属性描述符。
注意 如果代码输出目标版本小于ES5,属性描述符将会是undefined。
如果方法装饰器返回一个值,它会被用作方法的属性描述符。
下边看两个例子:
1.装饰器将传入方法的所有参数求和并精确到小数点指定位数:
function plusAllMoney(formatLength:number):Function{
return function(target:any,propertyKey:string,descriptor:TypedPropertyDescriptor<Function>){
const method = descriptor.value
descriptor.value = function(){
const total = Array.prototype.reduce.call(arguments,(t,c)=>{ return t+=c},0)
return (method as Function).call(this,(total as number).toFixed(formatLength))
}
}
}
class ObjFn {
constructor(){}
@plusAllMoney(2)
getMoney(...args:Array<number>){
console.log("传入的金额之和为:"+args[0])
return args[0]
}
}
let man = new ObjFn()
man.getMoney(3,4,5)
man.getMoney(12,34)
man.getMoney(1,2,3,4,5)
编译并运行,在控制台可以看到输出:
>> 传入的金额之和为:12.00
>> 传入的金额之和为:46.00
>> 传入的金额之和为:15.00
2.对类的方法进行枚举隐藏:
function enumerable(value:boolean){
return function(target:any,propertyKey:string,descriptor:PropertyDescriptor){
descriptor.enumerable = value
}
}
class ManFn {
name = "jack"
constructor(name?:string){
if(name) this.name = name
}
@enumerable(false)
sayHi(){
console.log("Hello,My name is " + this.name)
}
run(){}
}
let man = new ManFn()
for(let k in man){
console.log(k)
}
编译并运行,控制台输出:
>> name
>> run
在上边的例子中,我们把sayHi
方法加了装饰器@enumerable(false)
,从enumerable
装饰器函数中,我们看到有descriptor.enumerable = value
,也就是说,这个装饰器把sayHi
方法设置为了不可枚举。根目录运行tsc
,然后运行生成的js文件,可以看到for循环输出了name
和run
,sayHi
没有输出,也就是装饰器的不可枚举生效了。
关于类型PropertyDescriptor
,他内部有这么几个属性,跟Object.defineProperty
一样:
interface PropertyDescriptor {
configurable?: boolean;
enumerable?: boolean;
value?: any;
writable?: boolean;
get?(): any;
set?(v: any): void;
}
除了枚举,还可以设置其他属性。
好了,关于方法装饰器就介绍到这里,后续会介绍其他的装饰器,欢迎关注。