'console' é um erro indefinido para o Internet Explorer

375

Estou usando o Firebug e tenho algumas instruções como:

console.log("...");

na minha página. No IE8 (provavelmente versões anteriores também), recebo erros de script dizendo que 'console' é indefinido. Tentei colocar isso no topo da minha página:

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

ainda recebo os erros. Alguma maneira de se livrar dos erros?

user246114
fonte
4
Use typeofno seu if, ele evitará erros indefinidos: if(typeof console === "undefined") { var console = { log: function (logMsg) { } }; }
Flak DiNenno
21
console.log () funciona apenas quando a ferramenta de desenvolvimento do IE está aberta (sim, o IE é ruim). veja stackoverflow.com/questions/7742781/…
Adrien Seja
11
Melhor resposta a essa pergunta é stackoverflow.com/a/16916941/2274855
Vinícius Moraes
11
Ligação @Aprillion está quebrado, use esta em vez disso: github.com/h5bp/html5-boilerplate/blob/master/src/js/plugins.js
Alfred Bez

Respostas:

378

Tentar

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

Uma variável indefinida não pode ser referida diretamente. No entanto, todas as variáveis ​​globais são atributos com o mesmo nome do contexto global ( windowno caso de navegadores) e acessar um atributo indefinido é bom.

Ou use if (typeof console === 'undefined') console = ...se você quiser evitar a variável mágica window, consulte a resposta de @Tim Down .

kennytm
fonte
160
Para deixar claro para quem mais usa isso, coloque <script type="text/javascript"> if (!window.console) console = {log: function() {}}; </script>no topo da sua página! Obrigado Kenny.
Windowsgm
11
Que talvar console = console || { log: function() {} };
devlord
9
@lorddev Para usar essa abreviação, você precisa incluir window:var console = window.console || { log: function() {} };
jlengstorf 22/13
64
Droga ... você constrói um site legal, desenvolvendo-o para o seu navegador favorito. No final, você gasta de quatro a cinco horas, tornando-o compatível com todos os outros navegadores modernos, e depois de quatro a cinco dias, tornando-o compatível com o IE.
Israel
6
O problema com essa resposta é que se você estiver usando outro nome como debug, alertam, contar com o navegador que a falta console irá lançar uma exceção ver a melhor maneira de fazer isso stackoverflow.com/a/16916941/2274855
Vinícius Moraes
319

Cole o seguinte na parte superior do seu JavaScript (antes de usar o console):

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

O wrapper de fechamento da função é o escopo das variáveis ​​para não definir nenhuma variável. Isso protege contra indefinido consolee indefinido console.debug(e outros métodos ausentes).

EDIT: notei que o HTML5 Boilerplate usa código semelhante em seu arquivo js / plugins.js, se você estiver procurando por uma solução que (provavelmente) seja mantida atualizada.

Peter Tseng
fonte
14
Por que essa resposta tem tão poucos votos positivos? É o mais completo dos postados aqui.
precisa saber é
Por causa da data. Concordo absolutamente com as soluções de trabalho corretas. Eu acho que esse tópico precisa ser moderado. Desculpe pelo mau inglês.
Wo
Bastante completo, exceto que ele não vai tentar redirecionar o log para a função de log (se houver) para que todos os registros são perdidos
Christophe Roussy
5
Quando isso aconteceria exatamente? Este código deve definir apenas elementos que ainda não estão definidos.
Peter Tseng
4
Eu acho que de qualquer forma - (function () {...} ()) ou (function () {...}) () - trabalha realmente
Peter Tseng
73

Outra alternativa é o typeofoperador:

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

Outra alternativa é usar uma biblioteca de log, como meu próprio log4javascript .

Tim Down
fonte
Seria uma boa idéia alterar a atribuição não declarada em uma declaração adequada.
kangax
11
Você quer dizer usar var? Isso apenas confundiria as coisas aqui. Ou você quer dizer atribuir ao window.consoleinvés de console?
Tim Down
Usando var. Por que isso confundiria as coisas aqui?
kangax
2
Que discussão confusa. +1 na resposta original. Se eu pudesse dar +2, daria por fornecer um link para o seu próprio log4javascript. Obrigado OP!
Jay Taylor
8
@ yckart: No. typeofé garantido para retornar uma string e "undefined"é uma string. Quando os dois operandos são do mesmo tipo ==e ===são especificados para executar exatamente as mesmas etapas. O uso typeof x == "undefined"é uma maneira sólida de testar se xestá indefinido em qualquer escopo e em qualquer ambiente compatível com ECMAScript 3.
Tim Baixo
47

Para uma solução mais robusta, use este trecho de código (extraído do código-fonte do 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;
        }
    }
}());
Vinícius Moraes
fonte
13

Nos meus scripts, eu uso a abreviação:

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

ou, se não for possível ou possível editar todas as linhas do console.log, eu crio um console falso:

// 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
fonte
2
Erro de sintaxe. Por que não apenasif(!console) {console = {} ; console.log = function(){};}
Meekohi
11
Ou não apenas!window.console && (window.console = { log: function () { } });
Maksim Vi.
10

Você pode usar console.log()se tiver Developer Toolsaberto o IE8 e também usar a Consolecaixa de texto na guia Script.


fonte
7
Isso não é bom se você esquecer de trocar o código do console. O erro no IE8 irá impedir o seu código JS de trabalhar
yunzen
7
if (typeof console == "undefined") {
  this.console = {
    log: function() {},
    info: function() {},
    error: function() {},
    warn: function() {}
  };
}
inscrição
fonte
11
cavpt emptor: deve ser definido no nível global a que thisse refere window.
SGNL
7

Com base em duas respostas anteriores de

e as documentações para

Aqui está uma implementação de melhor esforço para o problema, ou seja, se existe um console.log que realmente existe, ele preenche as lacunas de métodos inexistentes via console.log.

Por exemplo, para o IE6 / 7, você pode substituir o registro por alerta (estúpido, mas funciona) e incluir o monstro abaixo (eu o chamei de console.js): [Sinta-se à vontade para remover comentários como achar melhor, eu os deixei para referência, um minimizador pode resolvê-los]:

<!--[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>

e 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
fonte
Não tenho certeza se precisamos methods.hasOwnProperty(method) && no loop for.
TWIStErRob
Tenho certeza de que você precisa.
ErikE
Fez um teste rápido no console do Chrome: > x = { a: 1, b: 2}-> Object {a: 1, b: 2}e for(var f in x) {console.log(f + " " + x[f]);} 'end'-> a 1 b 2 "end". Portanto, um objeto anônimo criado não possui nenhuma propriedade adicional e methodsé criado apenas antes do forloop. É possível hackear o que foi dito acima?
TWIStErRob
3
Sim. var x = { a: 1, b: 2}; Object.prototype.surprise = 'I\'m in yer objectz'; for (var f in x) {console.log(f, x[f]);}Você nunca sabe o que uma biblioteca fez com os objetos na cadeia de herança do objeto com o qual está trabalhando. Assim, a recomendação das ferramentas de qualidade de código javascript, como jshint e jslint, deve ser usada hasOwnProperty.
ErikE
6

No IE9, se o console não estiver aberto, este código:

alert(typeof console);

mostrará "objeto", mas esse código

alert(typeof console.log);

lançará a exceção TypeError, mas não retornará valor indefinido;

Portanto, a versão garantida do código será semelhante a esta:

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

Estou usando apenas console.log no meu código. Então eu incluo um forro 2 muito curto

var console = console || {};
console.log = console.log || function(){};
Ruben Decrop
fonte
11
Como está funcionando ... Não estou vendo nenhuma linha console.log impressa no navegador IE, testei com 2 sistemas diferentes em que 1 - console.log está funcionando e 2 sistemas não. Eu tentei em ambos, mas não é capaz de ver qualquer log em ambos os sistemas.
kiran
2

Percebeu que o OP está usando o Firebug com o IE, então suponha que seja o Firebug Lite . Esta é uma situação descolada, pois o console é definido no IE quando a janela do depurador é aberta, mas o que acontece quando o Firebug já está em execução? Não tenho certeza, mas talvez o método "firebugx.js" possa ser uma boa maneira de testar nesta situação:

fonte:

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() {}
    }

(links atualizados em 12/2014)

Roberto
fonte
1

Estou usando o fauxconsole ; Modifiquei um pouco o css para que pareça melhor, mas funcione muito bem.

Stijn Geukens
fonte
1

Para depuração no IE, confira este log4javascript

Praveen
fonte
Isso é ótimo, especialmente porque meu console do IE8 não produz nada.
Firsh - LetsWP.io
11
Obrigado por seus comentários.
Praveen
11
Eu estava procurando pelo comentário de outra pergunta aqui que dizia 'autopromoção desavergonhada' ou eu não conheço - semelhante - alguém que disse que criou esse scipt, foi você? Eu já fechei essa guia. Enfim, é uma ferramenta realmente ótima e muito útil para o meu projeto.
Firsh - LetsWP.io
11
@ Firsh Não criei este script, sou uma pessoa como você se beneficiou usando a ferramenta.
22813 Praveen
1

Para suporte ao IE8 ou console limitado ao console.log (sem depuração, rastreamento, ...), você pode fazer o seguinte:

  • Se console OU console.log indefinido: Crie funções fictícias para funções do console (rastreio, depuração, log, ...)

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

  • Caso contrário, se console.log estiver definido (IE8) E console.debug (qualquer outro) não estiver definido: redirecione todas as funções de log para console.log, isso permitirá manter esses logs!

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

Não tenho certeza sobre o suporte de declaração em várias versões do IE, mas todas as sugestões são bem-vindas. Também postou esta resposta aqui: Como posso usar o log do console no Internet Explorer?

Christophe Roussy
fonte
1
console = console || { 
    debug: function(){}, 
    log: function(){}
    ...
}
David Glass
fonte
1

Esboço do console no 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
fonte
0

Você pode usar o abaixo para dar um grau extra de seguro de que você tem todas as bases cobertas. Usar typeofprimeiro evitará undefinederros. O uso ===também garantirá que o nome do tipo seja realmente a sequência "indefinida". Por fim, convém adicionar um parâmetro à assinatura da função (eu escolhi logMsgarbitrariamente) para garantir consistência, pois você passa o que deseja imprimir no console para a função de log. Isso também mantém o intellisense preciso e evita avisos / erros no seu IDE ciente de JS.

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

Às vezes, o console funciona no IE8 / 9, mas falha em outros momentos. Esse comportamento irregular depende se você possui ferramentas de desenvolvedor abertas e está descrito na pergunta stackoverflow O IE9 suporta console.log e é uma função real?

Anon
fonte
0

Foi encontrado um problema semelhante ao executar console.log nas janelas filho no IE9, criado pela função window.open.

Parece que, nesse caso, o console é definido apenas na janela pai e é indefinido nas janelas filho até que você as atualize. O mesmo se aplica a filhos de janelas filho.

Eu lido com esse problema envolvendo o logon na próxima função (abaixo está o fragmento do módulo)

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);
    }
Max Venediktov
fonte
-2

Depois de ter tantos problemas com essa coisa (é difícil depurar o erro, pois se você abrir o console do desenvolvedor, o erro não acontece mais!) Decidi criar um código de exagero para nunca mais me preocupar com isso:

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

Pessoalmente, eu só uso console.log e console.error, mas esse código lida com todas as outras funções, como mostrado na Mozzila Developer Network: https://developer.mozilla.org/en-US/docs/Web/API/console . Basta colocar esse código no topo da sua página e você estará pronto para sempre.

Hoffmann
fonte
-11

Você pode usar o console.log (...) diretamente no Firefox, mas não no IEs. No IEs, você precisa usar o window.console.

Mohit Kumar
fonte
11
console.log e window.console.log se referem à mesma função em qualquer navegador que seja remotamente compatível com o ECMAscript. É uma boa prática usá-la para evitar que uma variável local oculte acidentalmente o objeto de console global, mas isso não tem absolutamente nada a ver com a escolha do navegador. console.log funciona bem no IE8 e no AFAIK não há capacidade de registro no IE6 / 7.
Tgr 26/10/10