访问器装饰器
访问器装饰器有3个参数分别是:
target
:原型key
:属性名descriptor
: 该属性的描述符
只能在getter或者setter其中一个增加装饰器,不可以同时加
function getNameDecoration(target: any, key: string, descriptor: any) {
console.log(target, key, descriptor)
}
class Test {
constructor(private _name: string) {}
@getNameDecoration
get name() {
return this._name;
}
set name(val: string) {
this._name = val;
}
}
const test = new Test('hello');
console.log(test.name);
属性装饰器
属性装饰器没有descriptor描述符,只有target和key
target
:原型key
:属性名
不能通过target[key]修改实例上的属性,因为target指向原型,修改的是原型上的属性,不是实例的属性。
function getNameDecoration(target: any, key: string) {
console.log(target, key);
}
class Test {
@getNameDecoration
name = 'tz';
}
const test = new Test();
test.name = 'hello';
console.log(test.name);
参数装饰器
参数装饰器可以对静态方法以及原型方法的参数进行处理
不同的是第三个参数是当前参数的索引值
target:静态方法执行类本身;原型方法指向原型
key:方法名(注意:不是参数名)
index: 当前参数的索引值
function paramsDecoration(target: any, key: string, index: number) {
console.log(target, key, index);
}
class Test {
static getInfo(@paramsDecoration name: string, age: number) {}
getInfo(@paramsDecoration name: string, age: number) {}
}
const test = new Test();
装饰器的应用
如下 userInfo如果为undefined,直接调用会报错;
如果单独给每个方法增加 try catch 有些冗余;
装饰器可以应用到此类场景
const userInfo: any = undefined;
function catchError(msg: string) {
return function (target: any, key: string, descriptor: any) {
const fn = descriptor.value;
descriptor.value = function () {
try {
fn();
} catch (e) {
console.log(`${msg}找不到`);
}
};
};
}
class Test {
@catchError('name')
getName() {
return userInfo.name;
}
@catchError('age')
getAge() {
return userInfo.age;
}
}
const test = new Test();
test.getName();
test.getAge();