推荐答案
在 TypeScript 中,装饰器是一种特殊类型的声明,它可以被附加到类声明、方法、访问器、属性或参数上。装饰器使用 @expression 的形式,其中 expression 必须是一个函数,它会在运行时被调用,被装饰的声明信息作为参数传入。
装饰器模式是一种结构型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原对象增加新的行为。在 TypeScript 中,装饰器可以用来实现装饰器模式,通过装饰器来动态地给对象添加额外的功能。
本题详细解读
1. 装饰器的基本使用
首先,我们需要定义一个装饰器函数。这个函数接收三个参数:
target: 对于静态成员来说是类的构造函数,对于实例成员来说是类的原型。propertyKey: 成员的名称。descriptor: 成员的属性描述符。
// 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`, args);
const result = originalMethod.apply(this, args);
console.log(`Called ${propertyKey}, result is`, result);
return result;
};
return descriptor;
}2. 应用装饰器
接下来,我们可以将这个装饰器应用到类的方法上:
// www.javascriptcn.com code example
class Calculator {
@log
add(a: number, b: number): number {
return a + b;
}
}
const calculator = new Calculator();
calculator.add(2, 3); // 输出: Calling add with [2, 3] 和 Called add, result is 53. 装饰器模式的实现
通过装饰器,我们可以动态地给对象添加额外的功能。例如,我们可以创建一个装饰器来缓存方法的返回值:
// www.javascriptcn.com code example
function cache(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
const cacheMap = new Map();
descriptor.value = function (...args: any[]) {
const key = JSON.stringify(args);
if (cacheMap.has(key)) {
return cacheMap.get(key);
}
const result = originalMethod.apply(this, args);
cacheMap.set(key, result);
return result;
};
return descriptor;
}
class Calculator {
@cache
add(a: number, b: number): number {
return a + b;
}
}
const calculator = new Calculator();
console.log(calculator.add(2, 3)); // 输出: 5
console.log(calculator.add(2, 3)); // 输出: 5 (从缓存中获取)在这个例子中,cache 装饰器会缓存 add 方法的返回值,当相同的参数再次传入时,直接从缓存中返回结果,而不需要重新计算。
4. 总结
通过 TypeScript 的装饰器,我们可以轻松地实现装饰器模式,动态地给对象添加额外的功能。装饰器可以应用于类、方法、属性等,使得代码更加灵活和可扩展。