包装`console.log`并保留调用堆栈

时间:2016-02-05 01:23:40

标签: javascript stack-trace callstack console.log

在我的日志助手类中,我有以下内容:

this.myInfo = console.info.bind(console);

当我从其他地方调用myInfo函数时,调用对象和行号被正确保留并记录在Chrome devtools中。

当我运行myInfo时,除了console.info之外,我还想运行另一个本地函数。因此,我想我可以包装上面的内容,它会工作。我想出了以下内容:

var obj = this;
this.myInfo = (function() {
    console.info.apply(this, arguments);
    myOtherFunc.apply(obj, arguments);
}).bind(console);

问题在于,与我的第一个示例不同,我丢失了console.info的调用上下文,并且在devTools中记录了错误的行号和文件。

如何包装第一个示例并保留console.info的正确上下文?

2 个答案:

答案 0 :(得分:2)

你可以使用getter。在getter中,您调用其他函数,然后将console.info.bind(console)返回给调用者。



Object.defineProperty(this, "myInfo", { get: function () { 
  myOtherFunc();
  return console.info.bind(console); 
}});




如果传递参数。您可以定义以下功能:



this.myInfo = function()
{
  myOtherFunc.apply(null, arguments);
  return console.bind.apply(console, arguments);
}
// example of call
this.myInfo(1,2,3)();




我有新的解决方案。您可以在单独的JS文件中实现console.log包装器,或者使用sourceURL对其进行评估,然后转到Chrome DevTools设置并添加" console-wrapper.js"当第一条消息到达控制台时,通过链接将url设置为blackbox模式或blackbox此脚本。 当脚本变为黑盒子时,所有消息将在源代码中具有正确的位置。 它适用于上一次谷歌Chrome Canary版本,并将在大约两个月内稳定下载。



eval("\
function myAwesomeConsoleLogWrapper() {\
  console.log.call(console, arguments);\
  makeAnotherWork();\
}\
//# sourceURL=console-wrapper.js");




答案 1 :(得分:0)

Alexey Kozyatinskiy的方法很酷。但是,如果不是像this.myInfo(1,2,3)()那样漂亮的代码比丑陋的控制台输出更严重的问题,你可以使用你在问题中发布的包装器并手动打印所需的文件名和行号,从new Error().stack中提取它。除非有一个团队在这个项目上工作,否则我会亲自使用Alexey的方法。