js实现decorator
JavaScript 装饰器实现
装饰器是一种特殊类型的声明,可以附加到类、方法、访问器、属性或参数上。装饰器使用 @expression 形式,expression 必须求值为一个函数,该函数会在运行时被调用。
类装饰器
类装饰器应用于类的构造函数,可以用来观察、修改或替换类定义。
function logClass(target) {
console.log('Class decorator applied to:', target.name);
return target;
}
@logClass
class MyClass {
constructor() {
console.log('MyClass instance created');
}
}
const instance = new MyClass();
方法装饰器
方法装饰器应用于方法的属性描述符,可以用来修改方法的行为。
function logMethod(target, propertyKey, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
console.log(`Calling method ${propertyKey} with args:`, args);
const result = originalMethod.apply(this, args);
console.log(`Method ${propertyKey} returned:`, result);
return result;
};
return descriptor;
}
class Calculator {
@logMethod
add(a, b) {
return a + b;
}
}
const calc = new Calculator();
calc.add(2, 3);
属性装饰器
属性装饰器应用于类的属性,可以用来修改属性的行为。
function readonly(target, propertyKey, descriptor) {
descriptor.writable = false;
return descriptor;
}
class Person {
@readonly
name = 'John';
}
const person = new Person();
person.name = 'Jane'; // 会报错,因为属性是只读的
访问器装饰器
访问器装饰器应用于访问器的属性描述符,可以用来修改 getter 或 setter 的行为。

function configurable(value) {
return function(target, propertyKey, descriptor) {
descriptor.configurable = value;
return descriptor;
};
}
class Circle {
private _radius: number;
constructor(radius: number) {
this._radius = radius;
}
@configurable(false)
get radius() {
return this._radius;
}
}
参数装饰器
参数装饰器应用于构造函数或方法的参数,可以用来添加元数据。
function validate(target, propertyKey, parameterIndex) {
console.log(`Validating parameter ${parameterIndex} of ${propertyKey}`);
}
class Greeter {
greet(@validate name: string) {
console.log(`Hello, ${name}`);
}
}
const greeter = new Greeter();
greeter.greet('World');
装饰器工厂
装饰器工厂是一个返回装饰器函数的函数,可以用来配置装饰器的行为。
function log(message: string) {
return function(target, propertyKey, descriptor) {
console.log(message);
return descriptor;
};
}
class Logger {
@log('Logging method called')
logMessage(message: string) {
console.log(message);
}
}
const logger = new Logger();
logger.logMessage('Hello, world!');
TypeScript 中的装饰器
在 TypeScript 中,需要启用 experimentalDecorators 编译器选项才能使用装饰器。

{
"compilerOptions": {
"experimentalDecorators": true
}
}
Babel 中的装饰器
使用 Babel 时,需要安装 @babel/plugin-proposal-decorators 插件来支持装饰器语法。
npm install --save-dev @babel/plugin-proposal-decorators
然后在 .babelrc 中配置插件:
{
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
注意事项
装饰器目前是 ECMAScript 的提案,尚未成为正式标准。在使用时需要注意兼容性问题。
装饰器的执行顺序是从上到下,从外到内。对于同一个目标,多个装饰器的应用顺序如下:
- 参数装饰器
- 方法/访问器/属性装饰器
- 类装饰器






