JavaScript中如何重写模块返回类的方法且无需修改原有调用代码
解决方案
以下三种方案都可以在不修改原有业务调用代码的前提下实现需求,可根据你的实际场景选择:
方案1:子类重写静态方法(推荐用于需要区分原生Logger和扩展Logger的场景)
你之前继承失败的核心原因是静态方法createFromConfig硬编码返回了基类Logger的实例,只需要在子类中重写该静态方法即可:
import logging from 'logging'; class DBLogger extends logging.Logger { // 重写静态方法,返回子类实例 static createFromConfig(key) { return new DBLogger(key); } error(...args) { // 你的额外逻辑 console.log('新增的错误处理逻辑', args); // 调用原生逻辑 super.error(...args); } } const dblogging = { Logger: DBLogger }; export default dblogging;
后续只需要把原有业务代码中导入logging的语句替换为导入你自定义的dblogging模块,其余所有调用代码完全不需要改动。
方案2:重写原型方法(推荐用于全局所有Logger实例都需要新增功能的场景)
如果需要让项目中所有Logger实例的error都自动具备新增功能,不需要修改任何导入语句和调用代码,只需要在项目入口处执行一次原型方法替换即可:
import logging from 'logging'; // 先保存原生error方法 const originalError = logging.Logger.prototype.error; // 重写原型上的error方法 logging.Logger.prototype.error = function(...args) { // 你的额外逻辑 console.log('新增的错误处理逻辑', args); // 调用原生逻辑,注意绑定this指向当前实例 originalError.apply(this, args); };
执行完上述代码后,项目中所有通过createFromConfig创建的Logger实例的error方法都会自动触发新增逻辑,原有业务代码不需要做任何修改。
方案3:修复实例方法重写逻辑(适用于仅需修改单个Logger实例的场景)
你之前直接重写实例方法的写法会触发死循环,因为重写后的方法内部调用的log.error已经是你重写后的方法了,只需要提前保存原生方法的引用即可:
import logging from 'logging'; const log = logging.Logger.createFromConfig('keyname'); // 保存原生error方法,绑定当前实例的this const originalError = log.error.bind(log); log.error = (...args) => { // 你的额外逻辑 console.log('新增的错误处理逻辑', args); // 调用原生逻辑 originalError(...args); };
内容的提问来源于stack exchange,提问作者Omiron
相关产品推荐
相关产品推荐

