【问题标题】:Wrapping `console.log` and retaining call stack包装 `console.log` 并保留调用堆栈
【发布时间】:2016-05-14 21:05:59
【问题描述】:

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

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

当我从其他地方调用我的 myInfo 函数时,调用对象和行号被正确保留并登录到 Chrome 开发工具中。

当我运行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 保留正确的上下文?

【问题讨论】:

  • 请问您为什么在控制台上使用bind?需要吗?
  • @userx01:是的,很多浏览器都需要作为方法调用。
  • 你试过console.trace吗?

标签: javascript stack-trace callstack console.log


【解决方案1】:

你可以使用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 添加到黑盒模式或在第一条消息到达控制台时通过链接将此脚本黑盒。 当脚本被黑盒化时,所有消息都将在源代码中具有正确的位置。 它在上一个 Google Chrome Canary 版本中运行,并将在大约两个月内稳定可用。

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

【讨论】:

  • 当您需要向myInfo 提供传递给myOtherFunc 的参数时,这并不适用。我已经更新了我的问题以反映这一要求。否则,相当整洁!
  • 添加了不是超级漂亮的解决方案来回答
  • 你是对的——它不漂亮!我会拭目以待,看看是否有其他人有明显更好的解决方案......它将在团队中使用,所以这几乎肯定会导致问题。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2014-10-21
    • 1970-01-01
    • 2020-07-21
    • 2011-11-20
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 2012-02-18
    • 2019-09-25
    相关资源
    最近更新 更多