如何安全地封装`console.log`?
如何安全地封装`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.call
或Object.call.call
,或者甚至isNaN.call.call
似乎同样有效,就像Function.prototype.call.call
一样。