js怎么实现装饰器
在JavaScript中实现装饰器(Decorator)主要依赖于ES7的装饰器提案,目前需要通过Babel等工具转译使用。以下是几种常见的实现方式和应用场景:
类装饰器
类装饰器接收目标类作为参数,可以修改或扩展类的行为。例如添加静态属性或拦截构造函数:

function logClass(target) {
target.prototype.log = function() {
console.log('Logged:', this);
};
return target;
}
@logClass
class MyClass {}
const instance = new MyClass();
instance.log(); // 输出: Logged: MyClass {}
方法装饰器
方法装饰器接收三个参数:目标对象、属性名和属性描述符。常用于日志记录或性能监控:
function readonly(target, name, descriptor) {
descriptor.writable = false;
return descriptor;
}
class Person {
@readonly
name() { return 'John' }
}
const person = new Person();
person.name = 'Alice'; // TypeError: Cannot assign to read only property
属性装饰器
属性装饰器接收目标对象和属性名,常用于元编程或属性初始化:

function format(formatString) {
return function(target, key) {
let value = target[key];
const getter = () => value;
const setter = (newVal) => {
value = formatString + newVal;
};
Object.defineProperty(target, key, {
get: getter,
set: setter
});
}
}
class User {
@format('Hello ')
greeting = 'World';
}
const user = new User();
console.log(user.greeting); // 输出: Hello World
参数装饰器
参数装饰器用于标记或修改方法参数,常见于依赖注入场景:
function validate(target, key, index) {
const validator = target[key].__validators || (target[key].__validators = []);
validator.push({
index,
validate: (value) => value !== undefined
});
}
class ApiService {
fetchData(@validate id) {
// 方法实现
}
}
装饰器工厂
通过高阶函数创建可配置的装饰器,增强灵活性:
function delay(ms) {
return function(target, key, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
setTimeout(() => {
originalMethod.apply(this, args);
}, ms);
};
return descriptor;
};
}
class Logger {
@delay(1000)
log(msg) {
console.log(msg);
}
}
new Logger().log('Delayed'); // 1秒后输出
注意事项
- 需要安装
@babel/plugin-proposal-decorators插件并配置legacy: true - 装饰器在TypeScript中需要启用
experimentalDecorators选项 - 装饰器执行顺序:参数装饰器 → 方法/属性装饰器 → 类装饰器(从下到上)
以上实现方式展示了装饰器在JavaScript中的核心应用模式,可根据实际需求组合使用这些技术方案。






