JavaScript 的 class 本身不原生支持装饰器,但该特性处于 ECMAScript Stage 3 提案阶段,已被 TypeScript 和 Babel 等工具通过编译转换支持;需配置启用(如 tsconfig.json 开启 experimentalDecorators),装饰器以 @ 符号写在类或成员前,分为类、方法、访问器和属性装饰器,用于增强行为或注入元信息。

JavaScript 的 class 语法本身不原生支持装饰器(Decorator),但装饰器是处于 Stage 3 提案阶段的 ECMAScript 特性,已被主流构建工具(如 TypeScript、Babel)广泛支持。要在类中使用装饰器扩展功能,需借助编译器转换 + 正确配置,而非直接在浏览器原生环境中运行。
装饰器的基本写法和作用位置
装饰器是一个函数,接收目标对象、属性名、属性描述符等参数,可修改类或类成员的行为。它通过 @ 符号写在声明前:
- 类装饰器:作用于整个类构造函数,可用于增强类、注册元信息、替换构造器等
- 方法装饰器:作用于类的方法,常用于日志、权限校验、防抖、缓存等
- 访问器(getter/setter)和属性装饰器:较少用,需注意属性初始化时机问题
在 TypeScript 中启用装饰器
TypeScript 对装饰器支持最成熟。需在 tsconfig.json 中开启:
{
"compilerOptions": {
"target": "ES2017",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
然后即可编写并使用:
立即学习“Java免费学习笔记(深入)”;
function readonly(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.writable = false;
}
class User {
@readonly
name = "Alice";
}
在 JavaScript(Babel)中启用装饰器
Babel 从 v7.22.0 起默认启用 decoratorAutoAccessors,但类装饰器仍需显式配置插件:
- 安装:
npm install --save-dev @babel/plugin-proposal-decorators - 在
.babelrc或babel.config.js中启用:
module.exports = {
plugins: [
["@babel/plugin-proposal-decorators", { version: "2023-01" }]
]
};
注意:Babel 当前(v7.x)推荐使用 version: "2023-01"(即 Stage 3 提案规范),而非旧版 "legacy" 模式。
常见实用装饰器示例
以下是一个带日志和自动绑定的组合装饰器(适用于 React 类组件或普通类):
function autobind(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
return originalMethod.apply(this, args);
};
}
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`[LOG] ${propertyKey} called with`, args);
return originalMethod.apply(this, args);
};
}
class Counter {
count = 0;
@autobind
@log
increment() {
this.count++;
}
}
调用 counter.increment() 时会自动绑定 this 并输出日志。
不复杂但容易忽略:装饰器执行顺序是从上到下(@autobind 先于 @log 被应用),而实际调用时是里层包装外层(log 包裹了 autobind 包裹后的方法)。务必注意装饰器函数的返回值是否正确透传原行为。


















