外观
装饰器是做什么的?
装饰器是加在类、方法或字段上的函数,用来在定义时修改或替换这个声明。TypeScript 和一些框架用它标注路由、依赖注入和日志。它现在仍是提案,语法以项目里启用的阶段为准,不要和已经稳定的类字段混为一谈。
原理
旧提案里,方法装饰器收到目标、属性名和描述符,可以改 descriptor.value,例如在调用前后打日志。类装饰器收到构造函数,可以返回一个新的构造函数。
新提案把装饰器的参数收成「值 + 上下文」。上下文里有种类(class、method、field)、名字和添加初始化逻辑的能力。TypeScript 5 的装饰器跟的是这一版。实验性的 experimentalDecorators 仍是旧语义,两套不能混用。
装饰器在类定义时执行,不是每次实例化都执行。它适合声明跨领域的行为。业务分支如果只在一个方法里出现,直接写在方法里更清楚。
追问
和高阶函数、Mixin 怎么选?
包一层函数就能完成的包装,用高阶函数。需要改类的方法和元数据、并且框架已经规定用装饰器时,跟着框架。Mixin 会把来源抹平,装饰器至少还标在声明旁边。
运行时还在吗?
装饰器是编译成函数调用的,产物里有真实代码。它不是 TypeScript 那种会被擦掉的类型。见 TypeScript 装饰器。
易错点
- 提案阶段不同,参数个数和返回值含义不同。先看
tsconfig开的是哪一套。 - 装饰器里的箭头函数如果包了原方法,
this要按原方法的调用方式转发。 - 多个装饰器的顺序是从下往上应用,和直觉可能相反。以所用规范为准,并在代码里少叠。