如何安全地封装`console.log`?

11 浏览
0 Comments

如何安全地封装`console.log`?

假设我想要在某些合法的生产环境中调用console.log,比如用于单元测试工具。显然,如果浏览器没有console,或者没有控制台,我不希望它抛出异常。

创建一个简单的log函数来将内容记录到控制台,或者在没有控制台的情况下静默失败而不报错,这应该是最好的方法。

上面链接中的问题的被接受答案是:

var log = Function.prototype.bind.call(console.log, console);
log.apply(console, ["this", "is", "a", "test"]);

在IE上,这个log函数能正常调用吗?这里使用apply只是为了展示它的可能性吗?我理解链接中的问题是,如果IE的控制台在运行时关闭,这个方法将失败,所以即使控制台打开后,log也无法工作,对吗?如果我理解错了,是否有人可以解释一下它是如何工作的?

这篇ycombinator文章似乎与之前链接的问题讨论的是同样的IE行为。

Function.prototype.apply.apply(console.log, [console, arguments]);

在IE9损坏的console.log上运行良好,也适用于其他供应商的常规console.log。

与使用Array.prototype.slice将arguments转换为真实数组的同样的技巧。

这在我的Chrome控制台上运行得很好。

function echo(){
  Function.prototype.apply.apply(console.log, [console, arguments]);
}

简化版:

function echo(){
  Function.apply.call(console.log, console, arguments);
}

添加检查和返回值:

function echo(){
  return window.console && console.log &&
         Function.apply.call(console.log, console, arguments);
}

我认为上面的示例足够好。但我手头没有IE来测试它,这种方法是否合理,以安全地包装console.log


更多问题

跟随下面nav的答案中的链接,我们看到代码:

Function.prototype.call.call(console.log, console,
    Array.prototype.slice.call(arguments));

在这种情况下,将arguments转换为数组的目的是什么?如果不这样做,我猜它在某些浏览器上会失败?而且,除了Opera的奇怪行为和没有控制台的浏览器之外,这样的方法在其他每个浏览器中都应该工作得很好,对吗?上面的示例中,prototype有什么作用,还是我们只是纠结不休...Function.call.callObject.call.call,或者甚至isNaN.call.call似乎同样有效,就像Function.prototype.call.call一样。

0