'consola' es un error indefinido para Internet Explorer

375

Estoy usando Firebug y tengo algunas declaraciones como:

console.log("...");

en mi pagina En IE8 (probablemente versiones anteriores también) recibo errores de script que dicen que 'consola' no está definida. Intenté poner esto en la parte superior de mi página:

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

Todavía me salen los errores. ¿Alguna forma de deshacerse de los errores?

usuario246114
fuente
44
Úselo typeofen su if, evitará errores indefinidos: if(typeof console === "undefined") { var console = { log: function (logMsg) { } }; }
Flak DiNenno
21
console.log () solo funciona cuando la herramienta de desarrollo de IE está abierta (sí, IE es horrible). ver stackoverflow.com/questions/7742781/…
Adrien Be
1
La mejor respuesta a esa pregunta es stackoverflow.com/a/16916941/2274855
Vinícius Moraes
1
El enlace @Aprillion está roto, use este en su lugar: github.com/h5bp/html5-boilerplate/blob/master/src/js/plugins.js
Alfred Bez

Respuestas:

378

Tratar

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

Una variable indefinida no se puede referir directamente. Sin embargo, todas las variables globales son atributos del mismo nombre del contexto global ( windowen el caso de los navegadores), y acceder a un atributo indefinido está bien.

O use if (typeof console === 'undefined') console = ...si desea evitar la variable mágica window, vea la respuesta de @Tim Down .

kennytm
fuente
160
¡Para ser claros para cualquier otra persona que use esto, colóquelo <script type="text/javascript"> if (!window.console) console = {log: function() {}}; </script>en la parte superior de su página! Gracias kenny
windowsgm
11
¿Qué pasavar console = console || { log: function() {} };
Devlord
99
@lorddev Para usar esa taquigrafía, debe incluir window:var console = window.console || { log: function() {} };
jlengstorf
64
Maldición ... construyes un buen sitio web, desarrollándolo para tu navegador favorito. Al final, pasa de 4 a 5 HORAS para que sea compatible con todos los demás navegadores MODERNOS, y luego pasa de 4 a 5 DÍAS para que sea compatible con IE.
Israel
66
El problema con esa respuesta es que si está usando otro nombre como depurar, advertir, contar con un navegador que carece de consola arrojará una excepción, vea la mejor manera de hacerlo stackoverflow.com/a/16916941/2274855
Vinícius Moraes
319

Pegue lo siguiente en la parte superior de su JavaScript (antes de usar la consola):

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

La envoltura de cierre de la función es abarcar las variables para no definir ninguna variable. Esto protege tanto contra indefinido consolecomo indefinido console.debug(y otros métodos faltantes).

EDITAR: Noté que HTML5 Boilerplate usa un código similar en su archivo js / plugins.js, si está buscando una solución que (probablemente) se mantenga actualizada.

Peter Tseng
fuente
14
¿Por qué esta respuesta tiene tan pocos votos positivos? Es el más completo de los publicados aquí.
mavilein 03 de
Por fecha. Absolutamente de acuerdo con las soluciones de trabajo correctas. Creo que este tema necesita ser moderado. Perdón por el mal inglés.
woto
Completamente, excepto que no intentará redirigir el registro a la función de registro (si está presente) para que todos los registros se pierdan
Christophe Roussy
55
¿Cuándo ocurriría esto exactamente? Este código solo debe definir elementos que aún no están definidos.
Peter Tseng
44
Creo que de cualquier manera - (function () {...} ()) o (function () {...}) () - funciona en realidad
Peter Tseng
73

Otra alternativa es el typeofoperador:

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

Otra alternativa es utilizar una biblioteca de registro, como mi propio log4javascript .

Tim Down
fuente
Sin embargo, sería una buena idea cambiar la asignación no declarada en una declaración adecuada.
kangax
1
¿Te refieres a usar var? Eso solo confundiría las cosas aquí. ¿O te refieres a asignar a window.consolemás que a console?
Tim Down
Utilizando var. ¿Por qué confundiría las cosas aquí?
kangax
2
Qué discusión tan confusa. +1 a la respuesta original. Si pudiera darle +2 lo haría por proporcionarle un enlace a su propio log4javascript. Gracias OP!
Jay Taylor
8
@yckart: No. typeofestá garantizado para devolver una cadena y "undefined"es una cadena. Cuando los dos operandos son del mismo tipo ==y ===se especifican para realizar exactamente los mismos pasos. El uso typeof x == "undefined"es una manera sólida de probar si xno está definido en ningún ámbito y en cualquier entorno compatible con ECMAScript 3.
Tim Down
47

Para una solución más robusta, use este código (tomado del código fuente de 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
fuente
13

En mis guiones, uso la abreviatura:

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

o, si no es posible o factible editar cada línea de console.log, creo una consola falsa:

// 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
fuente
2
Error de sintaxis. ¿Por qué no soloif(!console) {console = {} ; console.log = function(){};}
Meekohi
1
O no solo!window.console && (window.console = { log: function () { } });
Maksim Vi.
10

Puede usarlo console.log()si tiene Developer Toolsabierto en IE8 y también puede usar el Consolecuadro de texto en la pestaña de secuencia de comandos.


fuente
77
Esto no es bueno si olvida barrer el código de la consola. El error en IE8 evitará que su código JS funcione
yunzen
7
if (typeof console == "undefined") {
  this.console = {
    log: function() {},
    info: function() {},
    error: function() {},
    warn: function() {}
  };
}
insignificante
fuente
1
advertencia de emptor: esto debe definirse a nivel global donde se thisrefiere window.
Sgnl
7

Basado en dos respuestas anteriores de

y las documentaciones para

Aquí hay una implementación del mejor esfuerzo para el problema, lo que significa que si hay un console.log que realmente existe, llena los vacíos para los métodos no existentes a través de console.log.

Por ejemplo, para IE6 / 7, puede reemplazar el registro con alerta (estúpido pero funciona) y luego incluir el siguiente monstruo (lo llamé console.js): [Siéntase libre de eliminar los comentarios como mejor le parezca, los dejé como referencia, un minimizador puede abordarlos]:

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

y 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
fuente
No estoy seguro de si necesitamos methods.hasOwnProperty(method) && en el bucle for.
TWiStErRob
Estoy seguro de que lo necesitas.
ErikE
Hice una prueba rápida en la consola de Chrome: > x = { a: 1, b: 2}-> Object {a: 1, b: 2}y for(var f in x) {console.log(f + " " + x[f]);} 'end'-> a 1 b 2 "end". Por lo tanto, un objeto anónimo creado no tiene ninguna propiedad adicional, y methodssolo se crea antes del forciclo. ¿Es posible hackear lo anterior?
TWiStErRob
3
Si. var x = { a: 1, b: 2}; Object.prototype.surprise = 'I\'m in yer objectz'; for (var f in x) {console.log(f, x[f]);}Nunca se sabe lo que una biblioteca ha hecho a los objetos en la cadena de herencia del objeto con el que está trabajando. Por lo tanto, la recomendación de las herramientas de calidad de código JavaScript como jshint y jslint para usar hasOwnProperty.
ErikE
6

En IE9, si la consola no está abierta, este código:

alert(typeof console);

mostrará "objeto", pero este código

alert(typeof console.log);

lanzará la excepción TypeError, pero no devolverá un valor indefinido;

Entonces, la versión garantizada del código será similar a esto:

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

Solo estoy usando console.log en mi código. Así que incluyo un 2 liner muy corto

var console = console || {};
console.log = console.log || function(){};
Ruben Decrop
fuente
1
Cómo funciona ... No veo ninguna línea de console.log impresa en el navegador IE, he probado con 2 sistemas diferentes en los que 1 - console.log funciona y 2 sistemas no. Intenté en ambos pero no pude ver ningún registro en ambos sistemas.
kiran
2

Noté que OP está usando Firebug con IE, así que suponga que es Firebug Lite . Esta es una situación funky ya que la consola se define en IE cuando se abre la ventana del depurador, pero ¿qué sucede cuando Firebug ya se está ejecutando? No estoy seguro, pero quizás el método "firebugx.js" podría ser una buena forma de probar en esta situación:

fuente:

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

(enlaces actualizados 20/2014)

Roberto
fuente
1

Estoy usando fauxconsole ; Modifiqué un poco el CSS para que se vea mejor pero funcione muy bien.

Stijn Geukens
fuente
1

Para depurar en IE, consulte este log4javascript

Praveen
fuente
Esto es genial, especialmente porque mi consola IE8 no genera nada.
Firsh - LetsWP.io
1
@Firsh Gracias por tus comentarios.
Praveen
1
Estaba buscando el comentario sobre otra pregunta aquí que decía 'autopromoción descarada' o no sé, similar, alguien que dijo que creó este scipt, ¿eras tú? Ya cerré esa pestaña. De todos modos, es una gran herramienta y muy útil para mi proyecto.
Firsh - LetsWP.io
1
@Firsh No creé este script, soy una persona como usted beneficiada con la herramienta.
Praveen
1

Para IE8 o soporte de consola limitado a console.log (sin depuración, seguimiento, ...) puede hacer lo siguiente:

  • Si la consola O console.log no está definida: cree funciones ficticias para las funciones de la consola (rastreo, depuración, registro, ...)

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

  • De lo contrario, si console.log está definido (IE8) Y console.debug (cualquier otro) no está definido: redirija todas las funciones de registro a console.log, ¡esto permite mantener esos registros!

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

No estoy seguro sobre el soporte de afirmación en varias versiones de IE, pero cualquier sugerencia es bienvenida. También publiqué esta respuesta aquí: ¿Cómo puedo usar el inicio de sesión de consola en Internet Explorer?

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

Trozo de consola en 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
fuente
0

Puede usar el siguiente para dar un grado adicional de seguro que tiene todas las bases cubiertas. Usar typeofprimero evitará cualquier undefinederror. El uso ===también garantizará que el nombre del tipo sea en realidad la cadena "indefinida". Finalmente, querrá agregar un parámetro a la firma de la función (elegí logMsgarbitrariamente) para garantizar la coherencia, ya que pasa lo que desee impreso a la consola a la función de registro. Esto también lo mantiene intellisense preciso y evita advertencias / errores en su IDE JS.

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

Algunas veces la consola funcionará en IE8 / 9 pero fallará en otras ocasiones. Este comportamiento errático depende de si tiene abiertas herramientas de desarrollador y se describe en la pregunta de stackoverflow ¿IE9 admite console.log, y es una función real?

Luego
fuente
0

Se encontró un problema similar al ejecutar console.log en ventanas secundarias en IE9, creado por la función window.open.

Parece que en este caso la consola se define solo en la ventana principal y no está definida en las ventanas secundarias hasta que las actualice. Lo mismo se aplica a los hijos de ventanas infantiles.

Abordo este problema envolviendo el registro en la siguiente función (a continuación se muestra un fragmento del 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
fuente
-2

Después de tener tantos problemas con esto (es difícil depurar el error ya que si abres la consola del desarrollador, ¡el error ya no ocurre!) Decidí crear un código excesivo para no tener que volver a molestarme con esto nunca más:

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

Personalmente, solo uso console.log y console.error, pero este código maneja todas las demás funciones como se muestra en la red de desarrolladores de Mozzila: https://developer.mozilla.org/en-US/docs/Web/API/console . Simplemente ponga ese código en la parte superior de su página y habrá terminado para siempre con esto.

Hoffmann
fuente
-11

Puede usar console.log (...) directamente en Firefox pero no en IE. En IE, debe usar window.console.

Mohit Kumar
fuente
11
console.log y window.console.log se refieren a la misma función en cualquier navegador que sea remotamente compatible con ECMAscript. Es una buena práctica usar este último para evitar que una variable local sombree accidentalmente el objeto de la consola global, pero eso no tiene absolutamente nada que ver con la elección del navegador. console.log funciona bien en IE8, y AFAIK no tiene capacidad de registro en absoluto en IE6 / 7.
Tgr