es6装饰器是编译时执行的函数,以@开头,用于修饰类及方法:类装饰器接收target(构造函数)可添加静态/实例属性;方法装饰器接收target、name、descriptor,可修改方法行为;支持参数化、mixins、日志、缓存等;多装饰器按洋葱模型执行;需babel或ts配置支持。

ES6 装饰器(Decorator)本质是一个编译时执行的函数,用于注释或修改类及其方法的行为。它不是运行时动态操作,而是在代码转译(如通过 Babel)阶段就完成增强,语法以 @ 开头,只能用在类声明和类方法上(不能用于普通函数,因存在函数提升问题)。
修饰类:添加静态或实例属性
类装饰器接收一个参数:target,即类本身(等同于类的构造函数)。你可以借此直接修改类的静态成员,或通过 target.prototype 添加实例可用的属性或方法。
- 添加静态属性:
target.isTestable = true - 添加实例属性:
target.prototype.hasLogger = true - 支持传参:用高阶函数封装,如
@testable(true)→ 返回实际装饰器函数 - 实现 mixins:用
Object.assign(target.prototype, mixinObj)把多个对象方法混入原型
修饰类方法:控制行为与元信息
方法装饰器接收三个参数:target(类的原型对象)、name(方法名)、descriptor(属性描述符对象)。通过修改 descriptor 可改变方法的可写性、是否可枚举、甚至重写其逻辑。
- 设为只读:
descriptor.writable = false - 添加日志:
const oldFn = descriptor.value; descriptor.value = function() { console.log(...); return oldFn.apply(this, arguments); } - 缓存结果(memoize):利用
WeakMap存储 this + 参数组合对应的返回值 - 权限校验、防抖、节流等横切逻辑都可通过 descriptor 改写 value 实现
执行顺序与组合使用
当多个装饰器作用于同一目标(如一个方法),它们按“洋葱模型”执行:先从外到内求值(即装饰器函数本身被调用),再从内到外运行(返回的包装函数被触发)。
-
@decA @decB method()→ 先执行decA函数体,再执行decB函数体;随后调用时,先运行decB返回的包装逻辑,再运行decA的 - 类装饰器与方法装饰器互不干扰,各自独立作用于对应目标
- 装饰器不可用于私有字段(#field)或 getter/setter 以外的访问器(需确保 descriptor 结构匹配)
环境配置前提
浏览器和 Node.js 原生不支持装饰器语法,必须借助工具链转译:
- Babel 需启用插件:
@babel/plugin-proposal-decorators(推荐legacy: true模式兼容性更好) - TypeScript 中需开启
"experimentalDecorators": true编译选项 - VS Code 中可加配置
"javascript.implicitProjectConfig.experimentalDecorators": true消除报错提示
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











