面试题答案
一键面试原因
- 性能损耗:每次使用装饰器都创建新的函数实例,会导致额外的内存分配和垃圾回收开销。在大规模应用中,频繁创建实例会显著降低性能。
- 一致性问题:不同实例可能导致行为不一致,尤其是当装饰器内部维护状态时。例如,多个装饰器实例对同一目标元素的状态管理可能出现冲突。
一般做法
- 单例模式:
- 实现思路:通过一个函数来管理装饰器函数实例的创建,确保无论装饰器使用多少次,都只创建一个实例。
- 示例代码:
let singletonDecorator: ((target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void) | null = null;
function getSingletonDecorator(): (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void {
if (!singletonDecorator) {
singletonDecorator = function (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) {
// 装饰器逻辑
console.log(`Decorating ${propertyKey}`);
};
}
return singletonDecorator;
}
class MyClass {
@getSingletonDecorator()
myMethod() {}
}
- 模块级变量:
- 实现思路:利用TypeScript模块的特性,在模块顶层声明装饰器函数变量,模块加载时只初始化一次,后续使用的都是同一个实例。
- 示例代码:
// decorator.ts
export function myDecorator(target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) {
// 装饰器逻辑
console.log(`Decorating ${propertyKey}`);
}
// main.ts
import {myDecorator} from './decorator';
class MyClass {
@myDecorator
myMethod() {}
}
在上述代码中,myDecorator
在decorator.ts
模块中定义,模块加载时只创建一次,MyClass
中使用的是同一个myDecorator
实例。