推荐答案
// www.javascriptcn.com code example
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyKey} with arguments: ${JSON.stringify(args)}`);
const result = originalMethod.apply(this, args);
console.log(`Called ${propertyKey} and returned: ${JSON.stringify(result)}`);
return result;
};
return descriptor;
}
class MyClass {
@log
myMethod(arg1: string, arg2: number) {
return { arg1, arg2 };
}
}
const instance = new MyClass();
instance.myMethod("test", 123);本题详细解读
装饰器基础
装饰器是一种特殊类型的声明,它可以被附加到类声明、方法、访问器、属性或参数上。装饰器使用 @expression 的形式,其中 expression 必须是一个函数,它会在运行时被调用,被装饰的声明信息作为参数传入。
日志记录装饰器的实现
定义装饰器函数:
log函数是一个方法装饰器,它接收三个参数:target:对于静态成员是类的构造函数,对于实例成员是类的原型。propertyKey:被装饰的方法的名称。descriptor:被装饰方法的属性描述符。
保存原始方法:在装饰器内部,首先保存原始方法的引用
originalMethod。重写方法:通过修改
descriptor.value,将原始方法替换为一个新的函数。这个新函数在执行时会先打印日志,然后调用原始方法,并在原始方法执行后再次打印日志。返回描述符:最后返回修改后的
descriptor,以便 TypeScript 应用这些更改。
使用装饰器
在 MyClass 类中,myMethod 方法被 @log 装饰器修饰。当调用 myMethod 时,装饰器会自动记录方法的调用和返回结果。
输出示例
Calling myMethod with arguments: ["test",123]
Called myMethod and returned: {"arg1":"test","arg2":123}通过这种方式,装饰器可以轻松地为方法添加日志记录功能,而无需修改方法本身的代码。