1. 实现TypeScript函数装饰器
function callLogger(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
let callCount = 0;
const callHistory: any[] = [];
descriptor.value = function (...args: any[]) {
callCount++;
callHistory.push(args);
console.log(`Function ${propertyKey} called ${callCount} times.`);
console.log(`Arguments of this call:`, args);
return originalMethod.apply(this, args);
};
return descriptor;
}
2. 函数装饰器工作原理
- 定义:函数装饰器本质上是一个函数,它接受三个参数:
target
(对于类方法,target
是类的原型对象;对于普通函数,target
是函数本身),propertyKey
(被装饰函数的名称),descriptor
(包含被装饰函数的属性描述符)。
- 执行时机:在类定义或函数定义时,装饰器立即执行。它可以修改被装饰函数的行为,比如在上述代码中,我们通过修改
descriptor.value
来包装原函数,添加了调用次数记录和参数记录的功能。
3. 在类方法上使用装饰器
class MyClass {
@callLogger
myMethod(a: number, b: string) {
console.log(`Method executed with a = ${a} and b = ${b}`);
}
}
const instance = new MyClass();
instance.myMethod(42, "hello");
4. 兼容性处理
- 浏览器环境:现代浏览器(支持ES6及以上)可以直接使用上述代码,因为它们原生支持类和装饰器(需开启实验性特性,在TypeScript中默认支持)。
- Node.js环境:Node.js从较新版本开始支持ES6类和装饰器。确保Node.js版本足够新,并且在
tsconfig.json
中设置 "target": "es6"
或更高版本。如果使用较旧版本,可以通过 @babel/plugin-proposal-decorators
插件来转换装饰器代码。
5. 实际项目中的应用场景
- 日志记录:在开发和调试过程中,记录函数的调用次数和参数可以帮助定位问题,理解函数的实际使用情况。
- 性能监控:通过记录函数调用次数和每次调用的耗时,可以分析哪些函数是性能瓶颈,从而进行优化。
- 权限控制:在一些企业级应用中,可以在类方法上使用装饰器来检查用户权限,在调用方法前验证当前用户是否有权限执行该操作。