typescript装饰器

152 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

装饰器是什么?

顾名思义,装饰器的作用就是对某种东西进行装饰。它可以按照你的想法把功能预先处理好,然后在使用到的地方引用,即可激活装饰器中的功能。打个比方:工厂生产了一副暴龙眼镜,你购买后佩戴上。工厂根据某些要求设计生产了装饰器(暴龙眼镜),你戴上后装饰了自己,装饰器就激活了。

如何使用装饰器?

tssconfig.json中的配置:

"experimentalDecorators": true,
"emitDecoratorMetadata": true,   

TS中的装饰器,本质上是一个函数,它的作用是注释或修改类和类成员(类声明,类成员中的方法、访问器(getter/setter)、属性、方法参数)。可能这样说,概念还不清晰,下面通过讲解类装饰器来说明:

类装饰器就在类声明之前被声明。类装饰器被应用于类的构造函数,可以用来观察、修改或替换类定 义。

// 声明装饰器
const CarDecorator:ClassDecorator = (target:Function) => {
  console.log(target); // 装饰的类(这个例子中被Car这个类使用了,那么target就是Car)
}

// 使用装饰器
@CarDecorator
class Car {
  band:string = ''
  run(){}
}

通过Ctrl+鼠标左键按住上面代码中声明的装饰器的类型“ClassDecorator”,就可以发现TS源码中有四种装饰器(类装饰器、属性装饰器、方法装饰器、方法参数装饰器):

企业微信截图_20221205125652.png

下面我们要正式"生产"一个有用的装饰器:

// 声明装饰器
const CarDecorator:ClassDecorator = (target:Function) => {
  target.prototype.country = '德国'
}

// 使用装饰器
@CarDecorator
class Car1 {
  band:string = '宝马'
  run(){
    console.log(`${(this as any).country}${this.band}`);
  }
}

const car1 = new Car1()
car1.run() // 德国宝马

@CarDecorator
class Car2 {
  band:string = '奔驰'
  run(){
    console.log(`${(this as any).country}${this.band}`);
  }
}

const car2 = new Car2()
car2.run() // 德国奔驰

这个装饰器干了一件事:在使用者的原型上挂载一个通用属性“country”。 使用方式: "@" + 装饰器名称。

装饰器的本质是什么

装饰器的本质就是一个函数,它是一个语法糖。下面我们不用装饰器,直接使用函数调用的方式来改造一下:

// 声明装饰器
const CarDecorator:ClassDecorator = (target:Function) => {
  target.prototype.country = '德国'
}

// 使用装饰器
// @CarDecorator
class Car1 {
  band:string = '宝马'
  run(){
    console.log(`${(this as any).country}${this.band}`);
  }
}
CarDecorator(Car1) // 代替装饰器“@CarDecorator”
const car1 = new Car1()
car1.run() // 德国宝马

// @CarDecorator
class Car2 {
  band:string = '奔驰'
  run(){
    console.log(`${(this as any).country}${this.band}`);
  }
}
CarDecorator(Car2) // 代替装饰器“@CarDecorator”
const car2 = new Car2()
car2.run() // 德国奔驰

我们发现,两种方式,结果是一样的。

结语

我个人理解:装饰器就是个封装好的函数,把一些功能预先组装定义好,便于我们在类中使用。 我是第一次分享技术文章,如有错误之处,还望不吝指教。