解决截获 console.log 后输出位置错误的问题
当你截获 console.log
方法时,浏览器默认会显示截获代码的位置,而不是原始调用位置。这是因为控制台使用调用堆栈信息来确定输出位置。
解决方案
方法1:使用 Error 堆栈跟踪
const originalConsoleLog = console.log;
console.log = function() {
// 创建一个 Error 对象来获取堆栈跟踪
const error = new Error();
const stack = error.stack.split('\n');
// 通常第三个堆栈条目是原始调用位置
const callerLine = stack.length > 2 ? stack[2] : stack[1];
// 在输出前添加调用位置信息
const args = Array.from(arguments);
args.unshift(`[${callerLine.trim()}]`);
// 调用原始 console.log
originalConsoleLog.apply(console, args);
};
方法2:使用 Proxy 保持原始调用位置
console.log = new Proxy(console.log, {
apply(target, thisArg, argumentsList) {
// 在这里添加你的拦截逻辑
// ...
// 使用 Reflect.apply 保持原始调用位置
return Reflect.apply(target, thisArg, argumentsList);
}
});
方法3:使用 bind 保持上下文
const originalLog = console.log.bind(console);
console.log = function() {
// 你的拦截逻辑
// ...
// 使用绑定后的原始方法
originalLog.apply(console, arguments);
};
最佳实践
- 保持原始调用位置:使用
apply
或Proxy
来确保调用堆栈不被破坏 - 添加清晰标记:在拦截器中添加前缀或后缀,而不是完全替换输出
- 性能考虑:堆栈跟踪操作可能影响性能,生产环境中慎用
注意事项
- 这些方法在不同浏览器中可能有不同表现
- 复杂的堆栈解析可能在压缩代码后失效
- 某些浏览器扩展可能干扰堆栈跟踪
选择哪种方法取决于你的具体需求和目标浏览器支持情况。