在3月底,js的装饰器提案终于进入了stage3,同时其metadata部分单独拆开仍处于stage2阶段([详见](https://github.com/tc39/proposal-decorators/pull/454))。但是此装饰器却非平时我们广泛使用的装饰器。通过本文我们将了解下该js提案下装饰器的用法并对比和先前装饰器提案下用法的区别
在[babel-plugin-proposal-decorators](https://babeljs.io/docs/en/babel-plugin-proposal-decorators#docsNav)的文档我们可以看到,decorator提案之前主要经历了3个阶段+目前进入stage3阶段移除metadata的版本共4个版本。下文分别简称(legacy、2018-09、2021-12、stage3)
experimentalDecorators
的用法
metadata
部分,提案本身没有太大的改变。不出意外这也是以后作为标准的装饰器
我们广为使用的用法。即Typescript中tsconfig中配置experimentalDecorators:true
{
"compileOptions": {
"experimentalDecorators": true
}
}
或者@babel/plugin-proposal-decorators
配置
legacy: true
。注意:最新的@babel/plugin-proposal-decorators
已经将该配置迁移到version
字段,即version: legacy
legacy
下的装饰器更具体用法可以参考此前写的一篇文章2020的最后一天,不妨了解下装饰器。
装饰器函数的签名主要如下
type decorator = (
target: Target | Target.prototype,
propertyKey: string,
descriptor: PropertyDescriptor
) => Function | void;
本次进入stage3提案的用法
装饰器函数签名如下:
type Decorator = (value: Input, context: {
kind: string;
name: string | symbol;
access: {
get?(): unknown;
set?(value: unknown): void;
};
isPrivate?: boolean;
isStatic?: boolean;
addInitializer?(initializer: () => void): void;
}) => Output | void;
装饰器函数包含两个入参参数
1、被装饰的值本身
2、被装饰值的上下文信息
"class"|"method"|"getter"|"setter"|"field"|"accessor"
。表示装饰器的类型各种不同类型的装饰器如下
此外stage3对比legacy提案特有的两个用法
由于这两种用法在实际中很少特别使用这里只作简单差异化介绍
stage3对比legacy
Target
给装饰器函数descriptor
对象,而stage3中只提供被装饰的值以及和它有关的上下文对象。在stage3中修改一个属性的attribute是不可能的,并且 getter 和 setter 不是“合并”而是单独被装饰stage3对比2018-09