推荐答案
// www.javascriptcn.com code example
// 示例:使用装饰器增强类的方法
function log(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
console.log(`Calling ${name} with`, args);
const result = originalMethod.apply(this, args);
console.log(`Result of ${name}:`, result);
return result;
};
return descriptor;
}
class Calculator {
@log
add(a, b) {
return a + b;
}
}
const calc = new Calculator();
calc.add(2, 3); // 输出: Calling add with [2, 3] 和 Result of add: 5本题详细解读
什么是装饰器(Decorator)?
装饰器是一种特殊类型的声明,它可以被附加到类声明、方法、访问器、属性或参数上。装饰器使用 @expression 的形式,其中 expression 是一个函数,它会在运行时被调用,并传入被装饰的目标对象的相关信息。
装饰器的基本语法
装饰器的基本语法如下:
@decorator
class MyClass { }
// 或者
class MyClass {
@decorator
method() { }
}装饰器的类型
- 类装饰器:应用于类构造函数,可以用来观察、修改或替换类定义。
- 方法装饰器:应用于类的方法,可以用来修改方法的行为。
- 访问器装饰器:应用于类的访问器(getter/setter)。
- 属性装饰器:应用于类的属性。
- 参数装饰器:应用于类方法的参数。
装饰器的参数
装饰器函数接收三个参数:
target:被装饰的目标对象(类、方法、属性等)。name:被装饰的目标的名称(方法名、属性名等)。descriptor:描述符对象(对于方法和访问器装饰器)。
装饰器的返回值
装饰器函数可以返回一个新的描述符对象,或者直接修改传入的描述符对象。如果返回 undefined,则使用默认的描述符。
示例解析
在上面的示例中,log 装饰器被应用于 Calculator 类的 add 方法。装饰器函数 log 接收三个参数:
target:Calculator类的原型。name:方法名"add"。descriptor:add方法的描述符对象。
装饰器函数内部,我们保存了原始方法的引用,然后重写了 descriptor.value,在调用原始方法之前和之后分别打印日志。最后返回修改后的描述符对象。
使用场景
装饰器常用于以下场景:
- 日志记录
- 性能监控
- 权限控制
- 数据验证
- 缓存处理
注意事项
- 装饰器目前是 ECMAScript 的提案,尚未正式成为标准,但在 TypeScript 和 Babel 中已经得到支持。
- 装饰器的执行顺序是从上到下,从外到内。