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

Dag*_*bit 47 javascript console logging internet-explorer wrapper

假设我想console.log为某些合法的生产原因包含一些调用,比如像单元测试工具这样的东西.显然,如果浏览器没有console,或者如果没有控制台,我不希望这会抛出一个过早的异常.

创建一个简单的log函数来将内容记录到控制台的最佳方法是什么,或者如果没有控制台,则默默地失败而没有错误?

上面提到的问题的答案是:

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

可以log在IE上正常调用此函数,apply这里的使用只是为了表明它是可能的吗?并且,我从链接的问题中假设,如果IE的控制台在运行时关闭,这将失败,因此log即使在控制台打开后也无法工作,对吗?如果这是错的,有人可以解释它是如何工作的吗?

这篇ycombinator文章似乎很相关.他们是否正在谈论与上面链接的问题相同的IE行为?

Function.prototype.apply.apply(console.log, [console, arguments]);
Run Code Online (Sandbox Code Playgroud)

适用于IE9破解的console.log和其他供应商的常规console.log.与使用Array.prototype.slice将参数转换为实数组相同的hack.

这在我的chrome控制台中运行良好.

function echo(){
  Function.prototype.apply.apply(console.log, [console, arguments]);
}
Run Code Online (Sandbox Code Playgroud)

简化:

function echo(){
  Function.apply.call(console.log, console, arguments);
}
Run Code Online (Sandbox Code Playgroud)

添加支票并返回:

function echo(){
  return window.console && console.log &&
         Function.apply.call(console.log, console, arguments);
}
Run Code Online (Sandbox Code Playgroud)

上面的例子对我来说足够了.不过,我手头没有IE来测试它.这是安全包装的合理方法console.log吗?


更多问题

按照下面导航答案中的链接,我们看到代码:

Function.prototype.call.call(console.log, console,
    Array.prototype.slice.call(arguments));
Run Code Online (Sandbox Code Playgroud)

arguments在这种情况下转换为数组的目的是什么?我想如果你不这样做,它必须在某些浏览器中失败?并且,除了歌剧奇怪的行为和无控制台的浏览器之外,这样的东西不应该适用于其他所有浏览器吗?并且确实prototype在上面的例子中起到了作用,或者我们只是在迂腐... Function.call.call或者Object.call.call或者就此而言isNaN.call.call似乎也是如此Function.prototype.call.call.

dbr*_*rin 20

包装器的问题是它们会混淆日志消息源的文件名和行号.

简单的IE7及以下垫片,保留其他浏览器的行号:

/* console shim*/
(function () {
    var f = function () {};
    if (!window.console) {
        window.console = {
            log:f, info:f, warn:f, debug:f, error:f
        };
    }
}());
Run Code Online (Sandbox Code Playgroud)


Chr*_*isN 16

对不起,我的帖子中有一个错误.不知道我是怎么错过它的.

如果不存在,则创建全局控制台对象的PROPER方式:

if (typeof console === "undefined"){
    console={};
    console.log = function(){
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 人们可能会使用更多功能,例如断言,警告等. (7认同)

And*_*y E 7

这个日志功能可以在IE上正常调用,在这里使用apply只是为了表明它是可能的吗?

是的,是的.这个特定的例子直接针对相关问题的"它是一个真正的功能"部分.

并且,我从链接的问题中假设,如果IE的控制台在运行时关闭,这将失败,因此即使在控制台打开后日志也不会工作,对吗?

正确.正如我在该问题的答案中所解释的那样,console直到第一次为特定选项卡打开开发人员工具时才会公开该对象.大多数开发人员使用控制台垫片,在这种情况下,该Function#bind方法有点过时,因为您也可以使用该Function#apply.apply方法.

在这种情况下,将参数转换为数组的目的是什么?

没有一个,这是多余的.除非它是自定义日志实现,否则开发人员可能有理由将参数对象转换为数组.

在上面的例子中原型是否有用,或者我们只是迂腐...

嗯,是的,不.某些开发人员可能无意中更改Function.call为自定义函数或值.当然,它们也可能会破裂Function.prototype.call,但这种情况不太可能发生.


eto*_*xin 6

我喜欢用:

'console' in window && console.log("Boom!");
Run Code Online (Sandbox Code Playgroud)

它适用于所有浏览器,易于理解.