IE9支持console.log吗?它是一个真正的函数吗?

213

window.console.log在Internet Explorer 9中的哪些情况下被定义?

即使window.console.log被定义,window.console.log.applywindow.console.log.call仍未定义。为什么会这样?

[IE8相关问题:IE8中的console.log发生了什么?.]


3
看看这篇关于IE8-9控制台对象/函数的细节的优秀文章:http://whattheheadsaid.com/2011/04/internet-explorer-9s-problematic-console-object - Marc Climent
@MarcCliment,链接已失效。 - chakeda
@chakeda 我讨厌这种情况,这是来自Web存档的链接:https://web.archive.org/web/20140625085155/http://whattheheadsaid.com/2011/04/internet-explorer-9s-problematic-console-object - Marc Climent
7个回答

302
在Internet Explorer 9(和8)中,仅当为特定选项卡打开开发人员工具时,才会公开console对象。如果隐藏该选项卡的开发人员工具窗口,则console对象将保持暴露状态,以便您导航到的每个页面都可以使用。如果打开一个新选项卡,则必须为该选项卡打开开发人员工具,以便公开console对象。 console对象不是任何标准的一部分,它是文档对象模型的扩展。像其他DOM对象一样,它被认为是主机对象,并且不需要从Object继承,也不需要像本机ECMAScript函数和对象那样从Function继承其方法。这就是为什么这些方法上的applycall未定义的原因。在IE 9中,大多数DOM对象都得到了改进,以从本机ECMAScript类型继承。由于开发人员工具被认为是IE的扩展(尽管是内置扩展),因此它们显然没有像DOM的其余部分那样获得相同的改进。 值得注意的是,您仍然可以在一些console方法上使用一些Function.prototype方法,只需使用一些bind()技巧即可。
var log = Function.prototype.bind.call(console.log, console);
log.apply(console, ["this", "is", "a", "test"]);
//-> "thisisatest"

2
Firebug的console对象也是这样。 - Marcel Korpel
152
很不骄傲地说,我在为网页开发多年中一直以为所有主流浏览器都支持console.log。今天我花了一整天的时间弄清楚为什么IE9不喜欢我的脚本,现在我知道原因了——它在第一步就有一个console.log。这个问题很难调试,因为打开调试模式就能让这个bug立即消失:P谢谢澄清! - f055
2
昨天我也遇到了同样的问题。安装DebugBar帮助我更快地解决了这个问题,因为它不定义控制台对象。所以当我隐藏IE控制台但没有隐藏DebugBar时,我收到了后者的消息,提示有JavaScript错误(未定义控制台)。 - Simon A. Eugster
你应该在问题第一次出现在IE上的时候就去检查错误日志了 @f055 - Lucky Ali
7
Internet选项->高级->显示有关每个脚本错误的通知。网页开发者应该始终在IE中保留此选项。这将会告诉您有关console或log函数未定义的消息,具体的消息我记不清了。 - Seth Flowers

168
在你的JS代码开头定义以下内容是解决console.log问题的简单方法:
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };

这对我在所有浏览器中都有效。它创建了一个虚拟函数来模拟 console.log 当调试器不活动时。当调试器处于活动状态时,方法console.log被定义并正常执行。


8
更多信息及更健壮的控制台替换方案(包括其他控制台方法)请参考此处:https://dev59.com/Fmsz5IYBdhLWcg3wR1zC#15771110 - Zach Lysobey
@ZachL:具体来说,哪些是指的? - hakre
我的回答有一种方法:https://dev59.com/Fmsz5IYBdhLWcg3wR1zC#15771110。还可以看看这个:https://github.com/paulmillr/console-polyfill/blob/master/index.js - Zach Lysobey

14

我知道这是一个非常老的问题,但感觉这增加了一个有价值的解决控制台问题的可选方法。将以下代码放在对console.*的任何调用之前(因此是你的第一个脚本)。

// Avoid `console` errors in browsers that lack a console.
(function() {
    var method;
    var noop = function () {};
    var methods = [
        'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
        'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
        'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
        'timeStamp', 'trace', 'warn'
    ];
    var length = methods.length;
    var console = (window.console = window.console || {});

    while (length--) {
        method = methods[length];

        // Only stub undefined methods.
        if (!console[method]) {
            console[method] = noop;
        }
    }
}());

参考:
https://github.com/h5bp/html5-boilerplate/blob/v5.0.0/dist/js/plugins.js


10

只有在控制台打开时才会定义console.log。如果你想在你的代码中检查它,请确保在window属性内检查它

if (window.console)
    console.log(msg)

在IE9中,这会抛出异常并且不会正确工作。不要这样做。

if (console) 
    console.log(msg)

6

在阅读Marc Cliament上面评论的文章后,我现在已经将我的全能跨浏览器console.log函数更改为以下形式:

function log()
{
    "use strict";

    if (typeof(console) !== "undefined" && console.log !== undefined)
    {
        try
        {
            console.log.apply(console, arguments);
        }
        catch (e)
        {
            var log = Function.prototype.bind.call(console.log, console);
            log.apply(console, arguments);
        }
    }
}

1
只需使用 Function.prototype.apply.call(console.log, console, arguments); - Victor
@Victor,这绝对应该是唯一被接受的答案! - Pavel Frankov

0
我想提一下,如果您在所有版本的Windows上关闭开发人员工具并使用console.log,则IE9不会引发错误。在XP上会出现错误,但在Windows 7上不会出现。 因此,如果您总体上放弃了对WinXP的支持,那么直接使用console.log就可以了。

-1

怎么样...

console = { log : function(text) { alert(text); } }

1
这在某些情况下可能是一个可行的解决方法,但你实际上并没有回答问题。 - p.s.w.g

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接