前言
一直觉得装饰器的写法有种蜜汁好感和好奇,例如 @component
或者@connect(x, y)
。
装饰器在 React 和 Angular 中很常见,因为这两个框架很强调类,而装饰器的作用范围正是类和类成员,来看装饰器提案的一句话
Decorators make it possible to annotate and modify classes and properties at design time.
指出了装饰器作用对象,注意到最后三个单词 at design time
, 再抄袭一句话
装饰器对类的行为的改变,是代码编译时发生的,而不是在运行时。这意味着,装饰器能在编译阶段运行代码。也就是说,装饰器本质就是编译时执行的函数
装饰器对类的修改是一次性的,而且是在代码编译阶段完成装饰
看一个类装饰器
1 | export const decorator = (target, name, descriptor) => { |
以上包含了装饰器的基本使用,所谓装饰器本质上就是一个通过@
调用的特殊函数, 这个函数包括三个参数 target(类), name(key), descriptor(属性描述), 在作为类装饰器使用时没有 name 和 descriptor, 另外 descriptor 包含以下属性
1 | descriptor: { |
babel 环境配置
除了 env 之外 还需要安装以下依赖
yarn add -D babel-plugin-transform-decorators-legacy
1 | { |
类装饰器
对一个类进行装饰, 可以修改类的原型链
1 | // 添加类的装静态性 |
1 | // 修改原型链 -》 对类的每个实例都器作用 |
类成员装饰器
1 | // 标记某个类成员为只读 |
1 | // 对类方法进行装饰, 自定义参数 输出日志信息 |
TL; DR
总的来说
- 装饰器的是一个能够被
@
调用的特殊包装函数, - 装饰器只作用于类和类成员
- 装饰器函数能拿到对应的类或者对应的属性以及它的值和 descriptor 进行修改, 达到装饰的目的
- 装饰器对类成员的改变只在代码编译时发生