实现带console.log能力的客户端日志器:如何动态生成日志时间戳?
解决Logger时间戳动态生成并保留原生console行号的问题
你的问题核心在于:原代码中new Date().toISOString()是在绑定函数阶段执行的,也就是Logger初始化时就生成了固定的时间戳,而非每次调用日志方法时动态生成。
解决方案
我们可以放弃提前绑定参数的方式,改为在每次调用日志方法时动态生成时间戳,同时通过合适的写法保留原生console的行号信息。以下是两种可行实现:
方案一:简洁箭头函数版本(多数现代浏览器支持行号保留)
const LOG_LEVELS = { DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, NONE: 4, }; // 假设loglevel为外部定义的日志级别变量 const Logger = { debug: loglevel === LOG_LEVELS.DEBUG ? (...args) => { const timestamp = new Date().toISOString(); console.log(`${timestamp}: [DEBUG]`, ...args); } : () => {}, info: loglevel <= LOG_LEVELS.INFO ? (...args) => { const timestamp = new Date().toISOString(); console.log(`${timestamp}: [INFO]`, ...args); } : () => {}, warn: loglevel <= LOG_LEVELS.WARN ? (...args) => { const timestamp = new Date().toISOString(); console.log(`${timestamp}: [WARN]`, ...args); } : () => {}, error: loglevel <= LOG_LEVELS.ERROR ? (...args) => { const timestamp = new Date().toISOString(); console.error(`${timestamp}: [ERROR]`, ...args); } : () => {}, };
方案二:动态函数版本(确保行号完全正确)
如果需要严格保证所有浏览器都显示用户调用日志方法的行号,可以用new Function动态生成日志方法,避免包裹函数干扰行号追踪:
const LOG_LEVELS = { DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, NONE: 4, }; // 生成日志方法的工具函数 function createLoggerMethod(level, consoleMethod) { return new Function('...args', ` const timestamp = new Date().toISOString(); console.${consoleMethod}(\`\${timestamp}: [${level}]\`, ...args); `); } // 假设loglevel为外部定义的日志级别变量 const Logger = { debug: loglevel === LOG_LEVELS.DEBUG ? createLoggerMethod('DEBUG', 'log') : () => {}, info: loglevel <= LOG_LEVELS.INFO ? createLoggerMethod('INFO', 'log') : () => {}, warn: loglevel <= LOG_LEVELS.WARN ? createLoggerMethod('WARN', 'log') : () => {}, error: loglevel <= LOG_LEVELS.ERROR ? createLoggerMethod('ERROR', 'error') : () => {}, };
关键说明
- 动态时间戳:两种方案都在调用日志方法时才执行
new Date().toISOString(),确保每个日志条目使用当前调用时刻的时间。 - 行号保留:
- 箭头函数版本依赖现代浏览器的控制台优化,多数情况下会自动显示用户调用Logger方法的行号。
- 动态函数版本通过创建无文件关联的函数,让控制台直接追溯到用户的调用位置,兼容性更好。
内容的提问来源于stack exchange,提问作者devnull69
相关产品推荐
相关产品推荐

