代码示例
// 定义一个日志装饰器
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`调用前: 方法 ${propertyKey} 被调用,参数为:`, args);
const result = originalMethod.apply(this, args);
console.log(`调用后: 方法 ${propertyKey} 执行完毕,返回值为:`, result);
return result;
};
return descriptor;
}
class ExampleClass {
@log
exampleMethod(a: number, b: number) {
return a + b;
}
}
const example = new ExampleClass();
example.exampleMethod(1, 2);
原理解释
- 装饰器定义:装饰器本质上是一个函数,它接受三个参数:
target
(被装饰的目标,对于方法装饰器来说是类的原型对象)、propertyKey
(被装饰的属性名,即方法名)、descriptor
(属性描述符,包含了该方法的一些元信息,如value
、writable
等)。
- 保存原始方法:在装饰器函数中,我们首先保存原始方法的引用
originalMethod
,以便后续正常调用。
- 方法重定义:我们重新定义
descriptor.value
,也就是实际调用的方法。在新的方法中,先打印调用前的日志,包含方法名和传入的参数。然后通过apply
方法调用原始方法,并传递this
上下文和参数,获取返回值。最后打印调用后的日志,包含方法名和返回值。
- 类中使用:在
ExampleClass
类的exampleMethod
方法上使用@log
装饰器,这样当调用exampleMethod
时,就会触发装饰器中定义的逻辑,在方法调用前后打印日志。