«консоль» - неопределенная ошибка для Internet Explorer

375

Я использую Firebug и у меня есть несколько утверждений, таких как:

console.log("...");

на моей странице. В IE8 (возможно, и в более ранних версиях) я получаю ошибки скрипта, говорящие, что «console» не определена. Я попытался поместить это вверху моей страницы:

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

все еще я получаю ошибки. Есть ли способ избавиться от ошибок?

user246114
источник
4
Используйте typeofв вашем if, это позволит избежать неопределенных ошибок: if(typeof console === "undefined") { var console = { log: function (logMsg) { } }; }
Flak DiNenno
21
console.log () работает только тогда, когда открыт инструмент разработки IE (да, IE дерьмовый). см. stackoverflow.com/questions/7742781/…
Adrien Be
1
Лучший ответ на этот вопрос - stackoverflow.com/a/16916941/2274855
Виниций Мораес
1
Ссылка @Aprillion не работает, используйте ее: github.com/h5bp/html5-boilerplate/blob/master/src/js/plugins.js
Альфред Без

Ответы:

378

Пытаться

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

На неопределенную переменную нельзя ссылаться напрямую. Однако все глобальные переменные являются атрибутами одного и того же имени глобального контекста (window в случае браузеров), и доступ к неопределенному атрибуту - это нормально.

Или используйте, if (typeof console === 'undefined') console = ...если хотите избежать магической переменной window, см. Ответ @Tim Down .

kennytm
источник
160
Просто чтобы быть понятным всем, кто использует это, разместите <script type="text/javascript"> if (!window.console) console = {log: function() {}}; </script>вверху страницы! Спасибо Кенни.
WindowsGM
11
Как насчетvar console = console || { log: function() {} };
devlord
9
@lorddev Чтобы использовать это сокращение, вы должны включить window:var console = window.console || { log: function() {} };
jlengstorf
64
Черт ... ты создаешь хороший сайт, развивая его для своего любимого браузера. В конце вы тратите 4-5 часов, чтобы сделать его совместимым со всеми другими современными браузерами, а затем вы тратите 4-5 дней, чтобы сделать его совместимым с IE.
Израиль
6
Проблема с этим ответом заключается в том, что если вы используете другое имя, такое как отладка, предупредите, подсчитайте в браузере, в котором отсутствует консоль, вы получите исключение, посмотрите лучший способ сделать это stackoverflow.com/a/16916941/2274855
Vinícius Moraes
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 Boilerplate использует аналогичный код в своем файле js / plugins.js, если вы ищете решение, которое (вероятно) будет обновляться.

Питер Ценг
источник
14
Почему этот ответ так мало голосов? Это самый полный из тех, которые размещены здесь.
Mavilein
Из-за даты. Абсолютно согласен с правильными рабочими решениями. Я думаю, что эту тему нужно модерировать. Простите за плохой английский.
ВТО
Вполне завершенный, за исключением того, что он не будет пытаться перенаправить регистрацию в функцию журнала (если она есть), поэтому все журналы будут потеряны
Кристоф Руссси
5
Когда это произойдет в точности? Этот код должен определять только те элементы, которые еще не определены.
Питер Ценг
4
Я думаю, что в любом случае - (function () {...} ()) или (function () {...}) () - на самом деле работает
Питер Ценг
73

Другой альтернативой является typeofоператор:

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

Еще одна альтернатива - использовать библиотеку журналов, такую ​​как мой собственный log4javascript .

Тим Даун
источник
Хотя было бы неплохо изменить незадекларированное присваивание в правильное объявление.
Кангакс
1
Вы имеете в виду использование var? Это только запутает вещи здесь. Или ты имеешь в виду присвоение, window.consoleа не console?
Тим Даун
Использование var. С чего бы это здесь путать?
Кангакс
2
Что за запутанная дискуссия. +1 к оригинальному ответу. Если бы я мог дать +2, я бы дал ссылку на ваш собственный log4javascript. Спасибо ОП!
Джей Тейлор
8
@yckart: No. typeofгарантированно возвращает строку и "undefined"является строкой. Когда два операнда имеют одинаковый тип ==и ===определены для выполнения точно одинаковых шагов. Использование typeof x == "undefined"- это надежный способ проверить, xне определено ли значение в любой области и в любой среде, совместимой с ECMAScript 3.
Тим Даун
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 () {});
iblamefish
источник
2
Ошибка синтаксиса. Почему бы не простоif(!console) {console = {} ; console.log = function(){};}
Meekohi
1
Или не просто!window.console && (window.console = { log: function () { } });
Максим Ви.
10

Вы можете использовать, console.log()если у вас Developer Toolsоткрыт в IE8, а также вы можете использовать Consoleтекстовое поле на вкладке скрипта.


источник
7
Это не хорошо, если вы забыли поменять код консоли. Ошибка в IE8 помешает работе вашего кода JS
yunzen
7
if (typeof console == "undefined") {
  this.console = {
    log: function() {},
    info: function() {},
    error: function() {},
    warn: function() {}
  };
}
insign
источник
1
caveat emptor: это должно быть определено на глобальном уровне, к которому thisотносится window.
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];
            }
        }
    })();
TWiStErRob
источник
Я не уверен, что нам нужно 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() {};
}
bonbonez
источник
6

Я использую только console.log в моем коде. Так что я включаю очень короткий 2 лайнер

var console = console || {};
console.log = console.log || function(){};
Рубен Декроп
источник
1
Как это работает ... Я не вижу ни одной строки console.log, напечатанной в браузере IE, я протестировал на 2 разных системах, где в 1 - console.log работает, а в 2 - нет. Я попытался в обоих, но не смог увидеть ни одного журнала в обеих системах.
Киран
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

Я использую fauxconsole ; Я немного изменил CSS, чтобы он выглядел лучше, но работает очень хорошо.

Stijn Geukens
источник
1

Для отладки в IE, проверьте этот log4javascript

Praveen
источник
Это здорово, тем более что моя консоль IE8 ничего не выводит.
Firsh - LetsWP.io
1
@Firsh Спасибо за ваши комментарии.
Правин
1
Я искал здесь комментарий к другому вопросу, который говорил: «Бесстыдная самореклама» или я не знаю - похоже - кто-то, кто сказал, что он создал этот сценарий, это был ты? Я уже закрыл эту вкладку. В любом случае, это действительно отличный инструмент и очень полезный для моего проекта.
Firsh - LetsWP.io
1
@Firsh Я не создавал этот сценарий, я такой человек, как вы получили пользу от использования инструмента.
Правин
1

Для IE8 или поддержки консоли, ограниченной console.log (без отладки, трассировки, ...), вы можете сделать следующее:

  • Если console ИЛИ console.log не определено: создайте фиктивные функции для функций консоли (trace, debug, log, ...)

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

  • Иначе, если console.log определен (IE8) И console.debug (любой другой) не определен: перенаправьте все функции ведения журнала в console.log, это позволяет сохранить эти журналы!

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

Не уверен насчет поддержки assert в различных версиях IE, но любые предложения приветствуются. Также опубликовал этот ответ здесь: Как я могу использовать консольное ведение журнала в Internet Explorer?

Кристоф Русси
источник
1
console = console || { 
    debug: function(){}, 
    log: function(){}
    ...
}
Дэвид Гласс
источник
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: () => { },
    }
};
gdbdable
источник
0

Вы можете использовать нижеприведенную форму, чтобы получить дополнительную степень страховки, покрывающую все базы. Использование typeoffirst позволит избежать любых undefinedошибок. Использование ===также гарантирует, что имя типа на самом деле является строкой «undefined». Наконец, вы захотите добавить параметр в сигнатуру функции (я выбрал logMsgпроизвольно) для обеспечения согласованности, поскольку вы передаете все, что вы хотите, в консоль, функции журнала. Это также обеспечивает точность ваших сведений и позволяет избежать любых предупреждений / ошибок в вашей IDE-осведомленной среде JS.

if(!window.console || typeof console === "undefined") {
  var console = { log: function (logMsg) { } };
}
Flak DiNenno
источник
0

Обнаружена похожая проблема при запуске console.log в дочерних окнах IE9, созданного функцией window.open.

Кажется, что в этом случае консоль определяется только в родительском окне и не определяется в дочерних окнах, пока вы не обновите их. То же относится и к детям дочерних окон.

Я имею дело с этой проблемой, оборачивая журнал в следующую функцию (ниже фрагмент модуля)

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 , Просто поместите этот код в верхней части вашей страницы, и вы закончите с этим навсегда.

Hoffmann
источник
-11

Вы можете использовать console.log (...) напрямую в Firefox, но не в IE. В IE вы должны использовать window.console.

Мохит Кумар
источник
11
console.log и window.console.log ссылаются на одну и ту же функцию в любом браузере, который даже удаленно совместим с ECMAscript. Хорошей практикой является использование последней, чтобы избежать локальной переменной, случайно скрывающей глобальный объект консоли, но это не имеет абсолютно никакого отношения к выбору браузера. console.log отлично работает в IE8, а AFAIK вообще не поддерживает возможности ведения журнала в IE6 / 7.
Tgr