如何为Node.js中Core类的构造函数及方法挂载日志函数?
在Node.js的Core类中实现自动触发的统一日志挂载方案
嘿,我来给你分享几个实用的方案,帮你在Node.js的Core类里实现自动触发的统一日志功能——不管是构造函数初始化,还是func1、func2被调用,日志都会自动执行,完美适配站点级统一日志的需求,后续扩展也很方便~
方案1:重写类原型方法(无依赖、低侵入)
这个方案不需要额外依赖,也不用修改原Core类的代码,直接在导入后通过重写原型方法包裹日志逻辑,对原有业务代码侵入性极低。
首先定义你的统一日志函数(后续扩展只需要修改这个函数即可):
function logMethodCall(methodName) { // 这里可以扩展成更复杂的日志逻辑:写入文件、上报日志系统等 console.log(`[${new Date().toISOString()}] 方法 ${methodName} 被调用`); }
然后在导入Core类后进行包装:
// 导入原始Core类 const OriginalCore = require('./core.js'); // 保存原始方法的引用,避免覆盖后丢失逻辑 const originalFunc1 = OriginalCore.prototype.func1; const originalFunc2 = OriginalCore.prototype.func2; // 重写构造函数:触发构造日志 const Core = function(...args) { logMethodCall('constructor'); // 调用原始构造函数并返回实例 return new OriginalCore(...args); }; // 保持原型链一致,避免实例方法丢失 Core.prototype = OriginalCore.prototype; // 重写func1:添加日志逻辑 Core.prototype.func1 = function(...args) { logMethodCall('func1'); // 调用原始方法并返回结果 return originalFunc1.apply(this, args); }; // 重写func2:添加日志逻辑 Core.prototype.func2 = function(...args) { logMethodCall('func2'); return originalFunc2.apply(this, args); }; // 正常实例化与调用 const core = new Core(); core.func1(); // 自动触发日志 core.func2(); // 自动触发日志
方案2:ES装饰器(优雅、解耦)
如果你的Node.js版本支持ES装饰器(需要在package.json或tsconfig.json中开启experimentalDecorators配置),这个方案会让代码更整洁,日志逻辑和业务逻辑完全分离。
先定义装饰器函数:
function logMethodCall(methodName) { console.log(`[${new Date().toISOString()}] 方法 ${methodName} 被调用`); } // 方法装饰器:给单个方法添加日志 function logMethod(target, propertyKey, descriptor) { const originalMethod = descriptor.value; descriptor.value = function(...args) { logMethodCall(propertyKey); return originalMethod.apply(this, args); }; return descriptor; } // 类装饰器:给构造函数添加日志 function logClass(target) { const originalConstructor = target; const newConstructor = function(...args) { logMethodCall('constructor'); return new originalConstructor(...args); }; newConstructor.prototype = originalConstructor.prototype; return newConstructor; }
然后修改你的Core类,直接应用装饰器:
@logClass class Core { constructor(app) { // 原构造函数业务逻辑 } @logMethod func1() { // 原func1业务逻辑 } @logMethod func2() { // 原func2业务逻辑 } } module.exports = Core;
之后正常导入实例化,构造函数和方法调用都会自动触发日志,代码结构清晰,后续扩展日志逻辑只需要修改logMethodCall即可。
方案3:Proxy代理(极致灵活)
Proxy是ES6+的特性,通过代理Core类或实例,可以拦截所有方法调用,完全不需要修改原类代码,灵活性拉满,甚至可以动态控制哪些方法需要日志。
实现代码如下:
const OriginalCore = require('./core.js'); function logMethodCall(methodName) { console.log(`[${new Date().toISOString()}] 方法 ${methodName} 被调用`); } // 代理Core类,拦截构造函数和方法访问 const ProxiedCore = new Proxy(OriginalCore, { // 拦截构造函数调用 construct(target, args) { logMethodCall('constructor'); return new target(...args); }, // 拦截属性/方法访问 get(target, prop) { const value = target[prop]; // 如果是函数,就包裹日志逻辑 if (typeof value === 'function') { return function(...args) { logMethodCall(prop); return value.apply(this, args); }; } return value; } }); // 使用代理后的类实例化 const core = new ProxiedCore(); core.func1(); // 自动触发日志 core.func2(); // 自动触发日志
这个方案的优势是完全无侵入,后续可以轻松扩展规则,比如只给特定方法加日志、添加日志过滤条件等。
方案选择建议
- 若不想修改原类代码,优先选方案1或方案3;
- 若项目支持ES装饰器,方案2的代码最优雅、解耦性最好;
- 若需要动态调整日志规则,方案3的Proxy方式是最佳选择。
内容的提问来源于stack exchange,提问作者Nelson Owalo
相关产品推荐
相关产品推荐

