什么是装饰器
装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性或参数上,是一种在不改变原来类和使用继承的情况下,动态扩展对象功能。
同样,本质也不是什么高大上的结构,就是一个普通的函数,expression的形式其实是Object.defineProperty的语法糖
expression求值后必须也是一个函数,它会运行时被调用,被装饰的声明信息作为参数传入
使用方式
在ts里,要是会用,需要在tsconfig.json文件启动
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
类装饰
声明一个函数addAge 去给Class的属性 age添加年龄
function addAge(constructor:Function){
constructor.prototype.age = 18
}
@addAge
class Person{
name:string;
age!:number;
constructor(){
this.name = '张三'
}
}
let person = new Person();
console.log(person.age) //18
方法/属性装饰
参数装饰
访问器装饰
装饰器工厂
执行顺序
当多个装饰器应用于一个声明上,将由上至下依次对装饰器表达式求值,求值的结果会被当作函数,由下至上依次调用,例如如下:
function f() {
console.log("f(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("f(): called");
}
}
function g() {
console.log("g(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("g(): called");
}
}
class C {
@f()
@g()
method() {}
}
// 输出
f(): evaluated
g(): evaluated
g(): called
f(): called
应用场景
可以看到,使用装饰器存在两个显著的优点:
- 代码可读性变强了,装饰器命名相当于一个注释
- 在不改变原有代码情况下,对原来功能进行扩展
后面的使用场景中,借助装饰器的特性,除了提高可读性之后,针对已经存在的类,可以通过装饰器的特性,在不改变原有代码情况下,对原来功能进行扩展
