javascript原生不支持装饰器,需通过typescript或babel实验性配置启用;装饰器是作用于类及其成员的函数,按类型分为类、方法、访问器和属性装饰器,执行时机为定义时而非实例化时。

JavaScript 的 Class 语法本身不原生支持装饰器,但通过 TypeScript 或启用实验性 JavaScript 特性(如 Babel + `@babel/plugin-proposal-decorators`),可以将装饰器与 Class 结合使用。核心在于:装饰器是作用于类、方法、访问器、属性或参数的函数,它在定义时被调用,用于修改或增强目标行为。
装饰器如何作用于 Class
类装饰器接收一个参数:类的构造函数。它可以返回一个新的构造函数来替换原类,或直接修改原构造函数的原型/静态属性。
- 装饰器函数在类定义时执行,而非实例化时
- 必须显式启用实验性语法(如 Babel 配置中设置 legacy: true 或使用 stage-3 preset)
- TypeScript 中需开启 experimentalDecorators 编译选项
常见装饰器类型与写法
装饰器分为四类,均基于 Class 语法使用:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 类装饰器:作用于 class 关键字前,如 @logClass class Foo {}
- 方法装饰器:作用于类方法前,接收目标对象、方法名、属性描述符,可重写 descriptor.value 实现 AOP(如日志、防抖)
- 访问器装饰器:类似方法装饰器,但目标是 get/set
- 属性装饰器:作用于类字段(如 @readonly name = 'Alice'),注意它不接收属性初始值,仅用于元数据注册或后续初始化
实际结合示例(方法装饰器)
以下是一个防抖方法装饰器,配合 Class 使用:
function debounce(wait) {
return function(target, key, descriptor) {
const originalMethod = descriptor.value;
let timeoutId;
descriptor.value = function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => originalMethod.apply(this, args), wait);
};
};
}
class Button {
@debounce(300)
handleClick() {
console.log('按钮被点击');
}
}
调用 new Button().handleClick() 多次,实际执行间隔不低于 300ms。
注意事项与兼容性
- 原生 JavaScript 尚未标准化装饰器(截至 ECMAScript 2024,仍处于 Stage 3 提案)
- Babel 默认使用旧版装饰器语义(legacy: true),TypeScript 默认也兼容此模式;新版提案语法略有不同(如参数顺序、支持私有字段)
- 装饰器不能用于普通函数或箭头函数,只适用于 Class 及其成员
- 多个装饰器从上到下执行,但求值顺序是从下到上(类似数组 reduceRight)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










