Typescript装饰器

126 阅读2分钟
  • 装饰器是一种开发模式,是一种方法,可以注入到类、方法及属性上来拓展功能

一、类装饰器

  • 特点:无法传递参数

装饰器实际上就是一种方法,将需要注入的对象传入该对象中进行后续处理,例如:

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();

image-20230727151024832

可以理解为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

如果有多个装饰器装饰某一个类的时候,会先从上到下执行所有的装饰器工厂,获取到所有真正的装饰器后,在从下到上执行所有的装饰器