js 实现装饰器
装饰器基础概念
装饰器是一种特殊类型的声明,能够附加到类声明、方法、属性或参数上,以修改或扩展其行为。在 JavaScript 中,装饰器通过 @ 符号前缀使用,本质上是高阶函数。
环境配置
装饰器目前处于提案阶段(Stage 3),需通过 Babel 或 TypeScript 编译支持:
- Babel 配置:安装
@babel/plugin-proposal-decorators插件并启用legacy: true。 - TypeScript:在
tsconfig.json中设置"experimentalDecorators": true。
类装饰器
类装饰器接收目标类的构造函数作为参数,可用于修改或替换类定义:

function logClass(target) {
console.log(`Class ${target.name} decorated`);
return class extends target {
constructor(...args) {
super(...args);
console.log('Instance created');
}
};
}
@logClass
class MyClass {}
new MyClass(); // 输出: "Class MyClass decorated" 和 "Instance created"
方法装饰器
方法装饰器接收三个参数:目标类原型、方法名、属性描述符。常用于拦截或增强方法逻辑:
function logMethod(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
console.log(`Calling ${name} with args:`, args);
return originalMethod.apply(this, args);
};
return descriptor;
}
class Calculator {
@logMethod
add(a, b) {
return a + b;
}
}
new Calculator().add(2, 3); // 输出: "Calling add with args: [2, 3]"
属性装饰器
属性装饰器接收目标类原型和属性名,常用于标记或修改属性:

function readonly(target, key) {
Object.defineProperty(target, key, { writable: false });
}
class User {
@readonly
name = 'Alice';
}
const user = new User();
user.name = 'Bob'; // 报错: Cannot assign to read only property
参数装饰器
参数装饰器接收目标类原型、方法名和参数索引,通常用于依赖注入或参数验证:
function validateParam(target, methodName, paramIndex) {
console.log(`Validating parameter ${paramIndex} of ${methodName}`);
}
class ApiService {
fetchData(@validateParam id) {
return { data: `ID: ${id}` };
}
}
new ApiService().fetchData(123); // 输出: "Validating parameter 0 of fetchData"
装饰器工厂
通过高阶函数生成可配置的装饰器:
function delay(ms) {
return function(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
setTimeout(() => originalMethod.apply(this, args), ms);
};
return descriptor;
};
}
class Task {
@delay(1000)
run() {
console.log('Task executed after 1s');
}
}
new Task().run(); // 1秒后输出
注意事项
- 装饰器执行顺序:属性/方法/参数装饰器从右到左,类装饰器最后执行。
- 避免在装饰器中直接修改原型链,可能导致不可预期行为。
- 生产环境需确保编译工具链支持装饰器语法。






