- 装饰器是一种开发模式,是一种方法,可以注入到类、方法及属性上来拓展功能
一、类装饰器
- 特点:无法传递参数
装饰器实际上就是一种方法,将需要注入的对象传入该对象中进行后续处理,例如:
function func(target: any) {
target.prototype.userName = 'xxx';
}
@func
class Person {}
let p1 = new Person();
在该代码中@func相当于func(Person),于是本段代码的意义是为Person类的原型上添加一个userName属性
类装饰器是无法传入参数对函数进行配置的,例如本代码中无法控制func函数中userName的值,只能将其固定的写为xxx
如果需要灵活的配置装饰器需要使用装饰器工厂
二、装饰器工厂
装饰器工厂模式能够通过返回一个函数的方式灵活的配置装饰器,例如:
function func(target: any) {
return function(target: any) {
target.prototype.username = options.name;
target.prototype.userage = options.age;
}
}
@func({
name: 'name',
age: 18
})
class Person {}
let p1 = new Person();
可以理解为func()返回的函数作为了一个类装饰器,外部的函数作为了一个工厂,对参数进行配置
三、属性装饰器
属性装饰器用于装饰类内部的属性
function func(target: any, attr: any) {
console.log(target, attr);
target[attr] = 'xxx';
}
class Person {
@func
username: string;
}
const p = new Person();
在属性装饰器函数中需要传入两个参数,target表示被操作的对象,attr表示被操作的属性
同样的,属性装饰器本身是不能传入参数的,如果想要灵活的对参数进行配置,需要将函数配置为工厂模式
四、方法装饰器
-
方法装饰器用来装饰方法
- 第一个参数: 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
- 第二个参数: 是方法的名称
- 第三个参数: 是方法的描述修饰方法
五、装饰器组合
function demo1(target: any) {
console.log('demo1');
}
function demo2() {
console.log('demo2');
return function(target: any) {
console.log('demo2内部');
}
}
function demo3() {
console.log('demo3');
return function(target: any) {
console.log('demo3内部');
}
}
function demo4(target: any) {
console.log('demo4');
}
@demo1
@demo2()
@demo3()
@demo4
class Person {}
let p = new Person();
本示例中输出的顺序为:demo2、demo3、demo4、demo3内部、demo2内部、demo1
如果有多个装饰器装饰某一个类的时候,会先从上到下执行所有的装饰器工厂,获取到所有真正的装饰器后,在从下到上执行所有的装饰器