开启掘金成长之旅!这是我参与「掘金日新计划 · 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源码中有四种装饰器(类装饰器、属性装饰器、方法装饰器、方法参数装饰器):
下面我们要正式"生产"一个有用的装饰器:
// 声明装饰器
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() // 德国奔驰
我们发现,两种方式,结果是一样的。
结语
我个人理解:装饰器就是个封装好的函数,把一些功能预先组装定义好,便于我们在类中使用。 我是第一次分享技术文章,如有错误之处,还望不吝指教。