如何编写工厂函数修改JS类方法,添加日志功能?
给类的所有方法添加日志的工厂函数实现
直接上实现方案,核心思路是创建一个继承原类的新类,然后遍历原类原型上的方法,给每个方法包裹一层日志逻辑:
function withLogging(BaseClass) { // 新类继承原类,保留原类的所有属性和方法 class LoggedClass extends BaseClass {} // 遍历原类原型的所有可枚举方法 Object.entries(BaseClass.prototype).forEach(([methodName, originalMethod]) => { // 跳过构造函数,避免覆盖 if (methodName === 'constructor') return; if (typeof originalMethod !== 'function') return; // 重写方法,添加日志逻辑 LoggedClass.prototype[methodName] = function(...args) { // 自定义日志内容,可按需修改 console.log(`[日志] 执行方法: ${methodName}`); console.log(`[日志] 传入参数:`, args); console.log(`[日志] 当前实例:`, this); // 调用原方法,用apply绑定正确的this上下文 const result = originalMethod.apply(this, args); console.log(`[日志] 方法 ${methodName} 返回结果:`, result); return result; }; }); return LoggedClass; }
使用示例
先定义一个普通类:
class Calculator { constructor(base) { this.base = base; } add(num) { return this.base + num; } multiply(num) { return this.base * num; } }
然后用工厂函数包装:
const LoggedCalculator = withLogging(Calculator); const calc = new LoggedCalculator(10); calc.add(5); // 输出日志: // [日志] 执行方法: add // [日志] 传入参数: [5] // [日志] 当前实例: Calculator { base: 10 } // [日志] 方法 add 返回结果: 15 calc.multiply(3); // 输出日志: // [日志] 执行方法: multiply // [日志] 传入参数: [3] // [日志] 当前实例: Calculator { base: 10 } // [日志] 方法 multiply 返回结果: 30
关键细节说明
- 用
extends继承原类,确保新类完全保留原类的实例属性和原型方法 - 遍历原型方法时跳过
constructor,避免破坏类的构造逻辑 - 用
apply绑定this,保证原方法能正确访问实例的内部属性 - 闭包保存
originalMethod,避免循环遍历中变量被覆盖的问题 - 日志逻辑可按需自定义,比如添加时间戳、用
try/catch捕获原方法错误并记录等
内容的提问来源于stack exchange,提问作者jamk
相关产品推荐
相关产品推荐

