Internet Explorer的“控制台”是未定义的错误


375

我正在使用Firebug,并且有一些类似的语句:

console.log("...");

在我的页面中。在IE8(可能也是早期版本)中,我收到脚本错误,提示“控制台”未定义。我尝试将其放在页面顶部:

<script type="text/javascript">
    if (!console) console = {log: function() {}};
</script>

仍然我得到错误。有什么办法摆脱错误?


4
typeof在您的if中使用,它将避免未定义的错误: if(typeof console === "undefined") { var console = { log: function (logMsg) { } }; }
Flak DiNenno

21
console.log()仅在IE的开发工具处于打开状态时才有效(是的,IE很烂)。看到stackoverflow.com/questions/7742781/...
阿德里安成为



1
@Aprillion链接已损坏,请改用此链接:github.com/h5bp/html5-boilerplate/blob/master/src/js/plugins.js
Alfred Bez

Answers:


378

尝试

if (!window.console) console = ...

未定义的变量不能直接引用。但是,所有全局变量都是与全局上下文名称相同的属性(window对于浏览器而言),并且可以访问未定义的属性。

或者,if (typeof console === 'undefined') console = ...如果您想避免使用magic变量window,请使用@Tim Down的答案


160
为了让使用此工具的其他人都清楚,将其放置<script type="text/javascript"> if (!window.console) console = {log: function() {}}; </script>在页面顶部!谢谢肯尼。
windowsgm'7

11
怎么样var console = console || { log: function() {} };
devlord

9
@lorddev要使用该速记,您需要包括windowvar console = window.console || { log: function() {} };
jlengstorf,2013年

64
该死的……您建立了一个不错的网站,为您喜欢的浏览器开发了它。最后,您花费4-5小时使它与所有其他MODERN浏览器兼容,然后花费4-5天使它与IE兼容。
以色列

6
与回答的问题是,如果你使用的是像调试另一个名字,警告,与浏览器计数,缺乏控制台将抛出一个异常看到了更好的方式来做到这一点stackoverflow.com/a/16916941/2274855
维尼修斯赖斯

319

将以下内容粘贴到JavaScript的顶部(在使用控制台之前):

/**
 * Protect window.console method calls, e.g. console is not defined on IE
 * unless dev tools are open, and IE doesn't define console.debug
 * 
 * Chrome 41.0.2272.118: debug,error,info,log,warn,dir,dirxml,table,trace,assert,count,markTimeline,profile,profileEnd,time,timeEnd,timeStamp,timeline,timelineEnd,group,groupCollapsed,groupEnd,clear
 * Firefox 37.0.1: log,info,warn,error,exception,debug,table,trace,dir,group,groupCollapsed,groupEnd,time,timeEnd,profile,profileEnd,assert,count
 * Internet Explorer 11: select,log,info,warn,error,debug,assert,time,timeEnd,timeStamp,group,groupCollapsed,groupEnd,trace,clear,dir,dirxml,count,countReset,cd
 * Safari 6.2.4: debug,error,log,info,warn,clear,dir,dirxml,table,trace,assert,count,profile,profileEnd,time,timeEnd,timeStamp,group,groupCollapsed,groupEnd
 * Opera 28.0.1750.48: debug,error,info,log,warn,dir,dirxml,table,trace,assert,count,markTimeline,profile,profileEnd,time,timeEnd,timeStamp,timeline,timelineEnd,group,groupCollapsed,groupEnd,clear
 */
(function() {
  // Union of Chrome, Firefox, IE, Opera, and Safari console methods
  var methods = ["assert", "cd", "clear", "count", "countReset",
    "debug", "dir", "dirxml", "error", "exception", "group", "groupCollapsed",
    "groupEnd", "info", "log", "markTimeline", "profile", "profileEnd",
    "select", "table", "time", "timeEnd", "timeStamp", "timeline",
    "timelineEnd", "trace", "warn"];
  var length = methods.length;
  var console = (window.console = window.console || {});
  var method;
  var noop = function() {};
  while (length--) {
    method = methods[length];
    // define undefined methods as noops to prevent errors
    if (!console[method])
      console[method] = noop;
  }
})();

函数闭包包装器将变量的范围限定为不定义任何变量。这可以防止未定义console和未定义console.debug(以及其他缺少的方法)。

编辑:我注意到HTML5样板在其js / plugins.js文件中使用了类似的代码,如果您正在寻找一种(可能)保持最新的解决方案。


14
为什么这个答案很少投票?这是这里发布的最完整的文章之一。
mavilein 2013年

因为日期。绝对同意正确的工作解决方案。我认为这个话题需要缓和。对不起,英语不好。
woto

非常完善,只是它不会尝试将日志重定向到日志功能(如果存在),因此所有日志都将丢失
Christophe Roussy

5
什么时候会发生?此代码应仅定义尚未定义的元素。
彼得·曾

4
我认为(function(){...}())或(function(){...})()-都可以有效
曾荫权2015年

73

另一个选择是typeof运算符:

if (typeof console == "undefined") {
    this.console = {log: function() {}};
}

另一个选择是使用日志记录库,例如我自己的log4javascript


不过,最好将未声明的赋值更改为正确的声明。
kangax

1
你是说用var吗?这只会使这里的事情变得混乱。还是您是指分配给window.console而不是console
Tim Down'7

使用var。为什么会混淆这里的内容?
kangax

2
真是令人困惑的讨论。+1为原始答案。如果我可以给+2,我将提供指向您自己的log4javascript的链接。谢谢OP!
杰伊·泰勒

8
@yckart:typeof保证返回的字符串"undefined"是字符串。当两个操作数具有相同的类型==并且===被指定执行完全相同的步骤时。使用typeof x == "undefined"是一种坚实的方法,可以测试x在任何范围和任何符合ECMAScript 3的环境中是否未定义。
Tim Down

47

要获得更强大的解决方案,请使用以下代码(摘自twitter的源代码):

// 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;
        }
    }
}());

13

在我的脚本中,我要么使用速记:

window.console && console.log(...) // only log if the function exists

或者,如果不可能或不可行编辑每个console.log行,我会创建一个伪造的控制台:

// check to see if console exists. If not, create an empty object for it,
// then create and empty logging function which does nothing. 
//
// REMEMBER: put this before any other console.log calls
!window.console && (window.console = {} && window.console.log = function () {});

2
语法错误。为什么不干脆if(!console) {console = {} ; console.log = function(){};}
Meekohi

1
还是不只是!window.console && (window.console = { log: function () { } });
Maksim Vi。

10

您可以使用console.log(),如果你有Developer Tools在IE8打开,也可以使用Console脚本选项卡上的文本框中。


7
如果您忘记交换控制台代码,那么这不是很好。IE8中的错误将阻止您的JS代码正常工作
yunzen 2012年

7
if (typeof console == "undefined") {
  this.console = {
    log: function() {},
    info: function() {},
    error: function() {},
    warn: function() {}
  };
}

1
买者自负:这应该在全球范围内,其中被定义thiswindow
Sgnl

7

根据之前的两个答案

和有关的文档

这是针对此问题的尽力而为的实现,这意味着,如果实际上存在console.log,它将通过console.log填补不存在的方法的空白。

例如,对于IE6 / 7,您可以将日志记录替换为警报(愚蠢但可以使用),然后添加以下怪物(我称其为console.js):[您可以随意删除注释,我留作参考,最小化程序可以解决它们]:

<!--[if lte IE 7]>
<SCRIPT LANGUAGE="javascript">
    (window.console = window.console || {}).log = function() { return window.alert.apply(window, arguments); };
</SCRIPT>
<![endif]-->
<script type="text/javascript" src="console.js"></script>

和console.js:

    /**
     * Protect window.console method calls, e.g. console is not defined on IE
     * unless dev tools are open, and IE doesn't define console.debug
     */
    (function() {
        var console = (window.console = window.console || {});
        var noop = function () {};
        var log = console.log || noop;
        var start = function(name) { return function(param) { log("Start " + name + ": " + param); } };
        var end = function(name) { return function(param) { log("End " + name + ": " + param); } };

        var methods = {
            // Internet Explorer (IE 10): http://msdn.microsoft.com/en-us/library/ie/hh772169(v=vs.85).aspx#methods
            // assert(test, message, optionalParams), clear(), count(countTitle), debug(message, optionalParams), dir(value, optionalParams), dirxml(value), error(message, optionalParams), group(groupTitle), groupCollapsed(groupTitle), groupEnd([groupTitle]), info(message, optionalParams), log(message, optionalParams), msIsIndependentlyComposed(oElementNode), profile(reportName), profileEnd(), time(timerName), timeEnd(timerName), trace(), warn(message, optionalParams)
            // "assert", "clear", "count", "debug", "dir", "dirxml", "error", "group", "groupCollapsed", "groupEnd", "info", "log", "msIsIndependentlyComposed", "profile", "profileEnd", "time", "timeEnd", "trace", "warn"

            // Safari (2012. 07. 23.): https://developer.apple.com/library/safari/#documentation/AppleApplications/Conceptual/Safari_Developer_Guide/DebuggingYourWebsite/DebuggingYourWebsite.html#//apple_ref/doc/uid/TP40007874-CH8-SW20
            // assert(expression, message-object), count([title]), debug([message-object]), dir(object), dirxml(node), error(message-object), group(message-object), groupEnd(), info(message-object), log(message-object), profile([title]), profileEnd([title]), time(name), markTimeline("string"), trace(), warn(message-object)
            // "assert", "count", "debug", "dir", "dirxml", "error", "group", "groupEnd", "info", "log", "profile", "profileEnd", "time", "markTimeline", "trace", "warn"

            // Firefox (2013. 05. 20.): https://developer.mozilla.org/en-US/docs/Web/API/console
            // debug(obj1 [, obj2, ..., objN]), debug(msg [, subst1, ..., substN]), dir(object), error(obj1 [, obj2, ..., objN]), error(msg [, subst1, ..., substN]), group(), groupCollapsed(), groupEnd(), info(obj1 [, obj2, ..., objN]), info(msg [, subst1, ..., substN]), log(obj1 [, obj2, ..., objN]), log(msg [, subst1, ..., substN]), time(timerName), timeEnd(timerName), trace(), warn(obj1 [, obj2, ..., objN]), warn(msg [, subst1, ..., substN])
            // "debug", "dir", "error", "group", "groupCollapsed", "groupEnd", "info", "log", "time", "timeEnd", "trace", "warn"

            // Chrome (2013. 01. 25.): https://developers.google.com/chrome-developer-tools/docs/console-api
            // assert(expression, object), clear(), count(label), debug(object [, object, ...]), dir(object), dirxml(object), error(object [, object, ...]), group(object[, object, ...]), groupCollapsed(object[, object, ...]), groupEnd(), info(object [, object, ...]), log(object [, object, ...]), profile([label]), profileEnd(), time(label), timeEnd(label), timeStamp([label]), trace(), warn(object [, object, ...])
            // "assert", "clear", "count", "debug", "dir", "dirxml", "error", "group", "groupCollapsed", "groupEnd", "info", "log", "profile", "profileEnd", "time", "timeEnd", "timeStamp", "trace", "warn"
            // Chrome (2012. 10. 04.): https://developers.google.com/web-toolkit/speedtracer/logging-api
            // markTimeline(String)
            // "markTimeline"

            assert: noop, clear: noop, trace: noop, count: noop, timeStamp: noop, msIsIndependentlyComposed: noop,
            debug: log, info: log, log: log, warn: log, error: log,
            dir: log, dirxml: log, markTimeline: log,
            group: start('group'), groupCollapsed: start('groupCollapsed'), groupEnd: end('group'),
            profile: start('profile'), profileEnd: end('profile'),
            time: start('time'), timeEnd: end('time')
        };

        for (var method in methods) {
            if ( methods.hasOwnProperty(method) && !(method in console) ) { // define undefined methods as best-effort methods
                console[method] = methods[method];
            }
        }
    })();

我不确定是否需要methods.hasOwnProperty(method) && for循环。
TWiStErRob

我确定您确实需要它。
ErikE

在Chrome的控制台中进行了快速测试:> x = { a: 1, b: 2}-> Object {a: 1, b: 2}for(var f in x) {console.log(f + " " + x[f]);} 'end'-> a 1 b 2 "end"。因此,创建的匿名对象没有任何其他属性,methods只是在for循环之前创建的。是否可以破解以上内容?
TWiStErRob

3
是。var x = { a: 1, b: 2}; Object.prototype.surprise = 'I\'m in yer objectz'; for (var f in x) {console.log(f, x[f]);}您永远都不知道库对正在使用的对象的继承链中的对象做了什么。因此,建议由javascript代码质量工具(如jshint和jslint)使用hasOwnProperty
ErikE

6

在IE9中,如果未打开控制台,则此代码:

alert(typeof console);

将显示“对象”,但是此代码

alert(typeof console.log);

将抛出TypeError异常,但不返回未定义的值;

因此,保证版本的代码将类似于以下内容:

try {
    if (window.console && window.console.log) {
        my_console_log = window.console.log;
    }
} catch (e) {
    my_console_log = function() {};
}

6

我只在代码中使用console.log。所以我包括了一个很短的2班轮

var console = console || {};
console.log = console.log || function(){};

1
它是如何工作的...我没有看到任何console.log行打印到IE浏览器,我已经测试了2种不同的系统,其中1种-console.log有效,而2种系统无效。我尝试了两者,但在两个系统中都看不到任何日志。
kiran

2

注意OP正在将Firebug与IE一起使用,因此假设它是Firebug Lite。这是一种时髦的情况,因为在打开调试器窗口时在IE中定义了控制台,但是当Firebug已经运行时会发生什么?不确定,但是“ firebugx.js”方法可能是在这种情况下进行测试的好方法:

资源:

https://code.google.com/p/fbug/source/browse/branches/firebug1.2/lite/firebugx.js?r=187

    if (!window.console || !console.firebug) {
        var names = [
            "log", "debug", "info", "warn", "error", "assert",
            "dir","dirxml","group","groupEnd","time","timeEnd",
            "count","trace","profile","profileEnd"
        ];
        window.console = {};
        for (var i = 0; i < names.length; ++i)
            window.console[names[i]] = function() {}
    }

(更新的链接12/2014)



1

要在IE中进行调试,请查看此log4javascript


这很棒,特别是因为我的IE8控制台什么都不输出。
Firsh-LetsWP.io

1
@Firsh感谢您的评论。
Praveen

1
我一直在寻找关于这里另一个问题的评论,说“无耻的自我提升”,或者我不知道-类似-有人说他创造了这种秘密,是吗?我已经关闭了该标签。无论如何,这是一个非常好的工具,对我的项目非常有用。
Firsh-LetsWP.io 2013年

1
@Firsh我没有创建此脚本,我是一个像您从使用工具中受益的人。
Praveen

1

对于仅限于console.log的IE8或控制台支持(无调试,跟踪等),您可以执行以下操作:

  • 如果未定义console或console.log:为控制台功能(跟踪,调试,日志等)创建虚拟功能

    window.console = { debug : function() {}, ...};

  • 否则,如果已定义console.log(IE8)并且未定义console.debug(其他任何功能):将所有日志记录功能重定向到console.log,则可以保留这些日志!

    window.console = { debug : window.console.log, ...};

不确定各种IE版本中的断言支持,但是欢迎提出任何建议。还在此处发布此答案:如何在Internet Explorer中使用控制台日志记录?



1

TypeScript中的控制台存根:

if (!window.console) {
console = {
    assert: () => { },
    clear: () => { },
    count: () => { },
    debug: () => { },
    dir: () => { },
    dirxml: () => { },
    error: () => { },
    group: () => { },
    groupCollapsed: () => { },
    groupEnd: () => { },
    info: () => { },
    log: () => { },
    msIsIndependentlyComposed: (e: Element) => false,
    profile: () => { },
    profileEnd: () => { },
    select: () => { },
    time: () => { },
    timeEnd: () => { },
    trace: () => { },
    warn: () => { },
    }
};

0

您可以使用以下内容为您提供涵盖所有基础的额外保险。使用typeoffirst将避免任何undefined错误。使用===还将确保类型的名称实际上是字符串“ undefined”。最后,您将想要向函数签名添加一个参数(我logMsg任意选择)以确保一致性,因为您确实将要打印到控制台的所有内容都传递给了日志函数。这还可以确保您的智能感知准确,并避免在JS感知IDE中出现任何警告/错误。

if(!window.console || typeof console === "undefined") {
  var console = { log: function (logMsg) { } };
}


0

在window9.open函数创建的IE9子窗口中运行console.log时遇到类似问题。

似乎在这种情况下,控制台仅在父窗口中定义,而在子窗口中未定义,直到刷新它们为止。这同样适用于子窗口的子窗口。

我通过将日志包装在下一个函数中来解决此问题(以下是模块的片段)

getConsole: function()
    {
        if (typeof console !== 'undefined') return console;

        var searchDepthMax = 5,
            searchDepth = 0,
            context = window.opener;

        while (!!context && searchDepth < searchDepthMax)
        {
            if (typeof context.console !== 'undefined') return context.console;

            context = context.opener;
            searchDepth++;
        }

        return null;
    },
    log: function(message){
        var _console = this.getConsole();
        if (!!_console) _console.log(message);
    }

-2

在这件事上有太多问题之后(很难调试错误,因为如果打开开发者控制台,错误就不会再发生了!),我决定制作一个多余的代码,以至于再也不必为此烦恼了:

if (typeof window.console === "undefined")
    window.console = {};

if (typeof window.console.debug === "undefined")
    window.console.debug= function() {};

if (typeof window.console.log === "undefined")
    window.console.log= function() {};

if (typeof window.console.error === "undefined")
    window.console.error= function() {alert("error");};

if (typeof window.console.time === "undefined")
    window.console.time= function() {};

if (typeof window.console.trace === "undefined")
    window.console.trace= function() {};

if (typeof window.console.info === "undefined")
    window.console.info= function() {};

if (typeof window.console.timeEnd === "undefined")
    window.console.timeEnd= function() {};

if (typeof window.console.group === "undefined")
    window.console.group= function() {};

if (typeof window.console.groupEnd === "undefined")
    window.console.groupEnd= function() {};

if (typeof window.console.groupCollapsed === "undefined")
    window.console.groupCollapsed= function() {};

if (typeof window.console.dir === "undefined")
    window.console.dir= function() {};

if (typeof window.console.warn === "undefined")
    window.console.warn= function() {};

我个人只使用console.log和console.error,但是此代码处理了Mozzila开发人员网络中显示的所有其他功能:https : //developer.mozilla.org/en-US/docs/Web/API/console。只需将代码放在页面顶部,就可以做到这一点。


-11

您可以直接在Firefox中使用console.log(...),但不能在IE中使用。在IE中,您必须使用window.console。


11
console.log和window.console.log在甚至与ECMAscript远程兼容的任何浏览器中都引用相同的功能。优良作法是使用后者避免局部变量意外地遮盖全局控制台对象,但这与浏览器的选择绝对无关。console.log在IE8中工作正常,而AFAIK在IE6 / 7中根本没有日志记录功能。
Tgr
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.