类装饰器是JavaScript Stage 3提案中用于声明式增强类的语法,以@开头、接收构造函数为唯一参数,可返回新类替换原类,执行于类定义求值阶段。

类装饰器是 JavaScript 提案(TC39 Stage 3)中用于增强类定义的语法特性,它允许你在声明类时以声明式方式添加元数据、修改行为或注入逻辑,而无需侵入类内部实现。
装饰器的基本语法形式
装饰器是一个以 @ 开头的表达式,写在类(或类成员)声明之前,紧邻其上:
@decorator
class MyClass { }
装饰器可以是函数调用(如 @logged())、带参数的高阶函数,也可以是直接的函数引用(如 @sealed)。它会在类定义被求值时同步执行,并可返回一个新类来替换原类。
类装饰器的签名与作用时机
类装饰器函数接收**唯一参数:目标类的构造函数(constructor)**。它应在运行时返回一个类(构造函数),该返回值将替代原始类被绑定到标识符上:
立即学习“Java免费学习笔记(深入)”;
- 若不返回值(或返回
undefined),则使用原类; - 若返回一个函数(最好是构造函数),则该函数成为新的类;
- 装饰器执行发生在类定义完成但尚未被赋值给变量时(即“类定义求值阶段”)。
示例:
function deprecated(target) {
console.warn(`${target.name} is deprecated`);
return class extends target {
constructor(...args) {
super(...args);
console.warn("Warning: using deprecated class");
}
};
}
@deprecated
class OldService {}
装饰器工厂与参数化
为支持传参,通常使用“装饰器工厂”——一个返回装饰器函数的函数:
function logMethod(level = "info") {
return function(target, propertyKey, descriptor) {
const original = descriptor.value;
descriptor.value = function(...args) {
console[level](`Calling ${String(propertyKey)} with`, args);
return original.apply(this, args);
};
};
}
class Calculator {
@logMethod("debug")
add(a, b) {
return a + b;
}
}
注意:上述是**方法装饰器**写法;类装饰器本身不接收 propertyKey 或 descriptor,仅接收 constructor。
与 TypeScript 装饰器的区别
JavaScript 官方提案(Stage 3)的装饰器语法与旧版 TypeScript 实现存在关键差异:
- 官方提案中,类装饰器只接收
target(构造函数),不再有context对象(早期草案曾引入,但已移除); - 当前 Stage 3 草案中,装饰器不可读取或修改类字段/方法的 descriptor,也不提供元数据反射 API —— 这些需配合
reflect-metadata或未来提案; - TypeScript 的
experimentalDecorators模式仍基于旧语义,开启后可能与标准行为不兼容,生产环境应谨慎启用。
目前主流运行时(如 V8、SpiderMonkey)尚未原生支持,需依赖 Babel(@babel/plugin-proposal-decorators)转译,且推荐配置 version: "2023-11" 以对齐最新草案。


















