js实现decorator
装饰器(Decorator)基础概念
装饰器是一种特殊类型的声明,能够附加到类、方法、访问器、属性或参数上。装饰器通过@expression形式使用,其中expression求值后必须是一个函数。
启用装饰器语法
在JavaScript中,装饰器目前处于提案阶段(Stage 3),需要通过Babel或TypeScript进行转译才能使用:
- Babel需要
@babel/plugin-proposal-decorators插件 - TypeScript需在
tsconfig.json中启用experimentalDecorators
// tsconfig.json示例
{
"compilerOptions": {
"experimentalDecorators": true
}
}
类装饰器实现
类装饰器接收构造函数作为参数,可以修改或替换类定义:
function sealed(constructor) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class MyClass {}
方法装饰器实现
方法装饰器接收三个参数:目标对象、属性名和属性描述符:

function log(target, name, descriptor) {
const original = descriptor.value;
descriptor.value = function(...args) {
console.log(`Calling ${name} with`, args);
return original.apply(this, args);
};
return descriptor;
}
class Calculator {
@log
add(a, b) {
return a + b;
}
}
属性装饰器实现
属性装饰器接收目标对象和属性名,可用于修改属性描述符:
function readonly(target, key, descriptor) {
descriptor.writable = false;
return descriptor;
}
class User {
@readonly
name = 'John';
}
访问器装饰器
访问器装饰器与方法装饰器类似,应用于getter/setter:

function configurable(value) {
return function(target, key, descriptor) {
descriptor.configurable = value;
};
}
class Person {
@configurable(false)
get name() {
return 'default';
}
}
参数装饰器
参数装饰器应用于构造函数或方法参数:
function validate(target, key, index) {
// 添加参数验证逻辑
}
class ApiService {
fetch(@validate id) {
// ...
}
}
装饰器工厂模式
通过工厂函数创建可配置的装饰器:
function delay(ms) {
return function(target, key, descriptor) {
const original = descriptor.value;
descriptor.value = function(...args) {
setTimeout(() => {
original.apply(this, args);
}, ms);
};
};
}
class Logger {
@delay(1000)
log(msg) {
console.log(msg);
}
}
第三方装饰器库
常用装饰器工具库:
core-decorators:提供@deprecated、@debounce等实用装饰器lodash-decorators:提供Lodash函数对应的装饰器版本
import { deprecated } from 'core-decorators';
class MyClass {
@deprecated('Use newMethod instead')
oldMethod() {}
}
注意事项
- 装饰器执行顺序:参数装饰器 → 方法/访问器/属性装饰器 → 类装饰器
- 装饰器不能用于函数声明(仅适用于类和方法)
- TypeScript实现与Babel实现存在细微差异
- 装饰器中的
this绑定需要注意上下文






