推荐答案
在 JavaScript 中,装饰器模式可以通过高阶函数或 ES6 的装饰器语法来实现。以下是两种实现方式:
1. 使用高阶函数实现装饰器模式
// www.javascriptcn.com code example
function withLogging(fn) {
return function(...args) {
console.log(`Calling function: ${fn.name}`);
const result = fn.apply(this, args);
console.log(`Function ${fn.name} returned: ${result}`);
return result;
};
}
function add(a, b) {
return a + b;
}
const decoratedAdd = withLogging(add);
console.log(decoratedAdd(2, 3)); // 输出: Calling function: add, Function add returned: 5, 52. 使用 ES6 装饰器语法实现装饰器模式
// www.javascriptcn.com code example
function loggingDecorator(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
console.log(`Calling method: ${name}`);
const result = originalMethod.apply(this, args);
console.log(`Method ${name} returned: ${result}`);
return result;
};
return descriptor;
}
class Calculator {
@loggingDecorator
add(a, b) {
return a + b;
}
}
const calc = new Calculator();
console.log(calc.add(2, 3)); // 输出: Calling method: add, Method add returned: 5, 5本题详细解读
1. 高阶函数实现装饰器模式
在高阶函数的实现中,withLogging 是一个装饰器函数,它接受一个函数 fn 作为参数,并返回一个新的函数。这个新函数在调用原始函数之前和之后分别打印日志信息。通过这种方式,我们可以在不修改原始函数的情况下,为其添加额外的行为。
2. ES6 装饰器语法实现装饰器模式
ES6 装饰器语法允许我们使用 @ 符号来修饰类的方法或属性。loggingDecorator 是一个装饰器函数,它接受三个参数:target(类的原型对象)、name(方法名)和 descriptor(属性描述符)。在装饰器函数内部,我们修改了原始方法的 value,使其在调用前后打印日志信息。
3. 装饰器模式的应用场景
装饰器模式通常用于以下场景:
- 日志记录:在函数或方法调用前后添加日志记录。
- 权限检查:在函数或方法调用前检查用户权限。
- 缓存:在函数或方法调用前检查缓存,避免重复计算。
- 性能监控:在函数或方法调用前后记录执行时间。
通过装饰器模式,我们可以将核心逻辑与附加功能分离,使代码更加模块化和可维护。