consola.registro.aplicar no trabajar en IE9


Parece que he reinventado la rueda, pero de alguna manera esto no está funcionando en Internet Explorer 9, pero lo hace en IE6.

function debug()
  if(!window.console) { 
    window.console = { log: function() { /* do something */ } };
  }
  console.log.apply(console, arguments);
}

Relacionados: Pregunta Apply () para javascript

El depurador F12 me dice que este "objeto" (consola.log) no admite el método 'apply'. ¿Ni siquiera se reconoce como una función? ¿Algún otro consejo o idea?

Author: Community, 2011-04-04

7 answers

La segunda parte de una respuesta que di recientemente también responde a esta pregunta. No considero que esto sea un duplicado de ese, así que, por conveniencia, lo pegaré aquí:

El objeto de consola no forma parte de ningún estándar y es una extensión del Modelo de Objetos de documento. Al igual que otros objetos DOM, se considera un objeto host y no se requiere heredar de Object, ni sus métodos de Function, como lo hacen las funciones y objetos nativos de ECMAScript. Esta es la razón de aplicar y call son indefinidos en esos métodos. En IE 9, la mayoría de los objetos DOM fueron mejorados para heredar de los tipos nativos de ECMAScript. Como las herramientas para desarrolladores se consideran una extensión de IE (aunque, una extensión incorporada), claramente no recibieron las mismas mejoras que el resto del DOM.

Por si sirve de algo, todavía puede usar alguna función.métodos de prototipo en métodos de consola con un poco de magia bind ():

var log = Function.prototype.bind.call(console.log, console);
log.apply(console, ["this", "is", "a", "test"]);
//-> "thisisatest"

Para que pueda arreglar todos los métodos console para IE 9 de la misma manera:

if (Function.prototype.bind && window.console && typeof console.log == "object"){
    [
      "log","info","warn","error","assert","dir","clear","profile","profileEnd"
    ].forEach(function (method) {
        console[method] = this.bind(console[method], console);
    }, Function.prototype.call);
}

Esto reemplaza las funciones "host" con funciones nativas que llaman a las funciones "host". Puede hacerlo funcionar en Internet Explorer 8 incluyendo las implementaciones de compatibilidad para Function.prototype.bind y Array.prototype.forEach en su código, o reescribir el fragmento de código anterior para incorporar las técnicas utilizadas por esos métodos.

Véase también

 91
Author: Andy E,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:01

También está la forma de hacerlo de Paul Irish. Es más simple que algunas de las respuestas anteriores, pero hace que log siempre genere una matriz (incluso si solo se pasó un argumento):

// usage: log('inside coolFunc',this,arguments);
// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
  log.history = log.history || [];   // store logs to an array for reference
  log.history.push(arguments);
  if(this.console){
    console.log( Array.prototype.slice.call(arguments) );
  }
};
 5
Author: BishopZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-10 19:52:31

Varias de las funciones de objeto host de IE no son realmente funciones JavaScript y por lo tanto no tienen apply o call. (alert, por ejemplo.)

Así que tendrás que hacerlo de la manera difícil:

function debug()
  var index;

  if(!window.console) { 
    window.console = { log: function() { /* do something */ } };
  }
  for (index = 0; index < arguments.length; ++index) {
      console.log(arguments[index]);
  }
}
 2
Author: T.J. Crowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-04 13:15:59

Me encontré con el mismo problema de IE e hice una rutina para ello. No es tan elegante como todas las implementaciones anteriores, pero funciona en TODOS los navegadores modernos.

Lo probé con Firefox (Firebug), ES decir, 7,8,9 Chrome y Opera. Hace uso de la EVAL EVIL, pero solo querrás depurar en desarrollo. Después reemplazará el código con debug = function () {};

Así que aquí está.

Saludos, Hans

(function(ns) {
  var msgs = [];

  // IE compatiblity
  function argtoarr (args,from) {
    var a = [];
    for (var i = from || 0; i<args.length; i++) a.push(args[i]);
    return a;    
  }

  function log(arg) {
    var params = "", format = "", type , output,
        types = {
            "number" : "%d",
            "object" : "{%o}",
            "array" : "[%o]"
        };
    for (var i=0; i<arg.length; i++) {
        params += (params ? "," : "")+"arg["+i+"]";
        type = types[toType(arg[i])] || "%s";
        if (type === "%d" && parseFloat(arg[i]) == parseInt(arg[i], 10)) type = "%f";
        format += (format ? "," : "")+type;
    }
    // opera does not support string format, so leave it out
    output = "console.log("+(window.opera ? "" : "'%f',".replace("%f",format))+"%p);".replace("%p",params);
    eval(output);
  }

  ns.debug = function () {
    msgs.push(argtoarr(arguments));
    if (console !== undefined) while (msgs.length>0) log(msgs.shift());
  }

})(window);

Oops olvidé mi función toType, aquí está.

function toType(obj) {
    if (obj === undefined) return "undefined";
    if (obj === null) return "null";
    var m = obj.constructor;
    if (!m) return "window";
    m = m.toString().match(/(?:function|\[object)\s*([a-z|A-Z|0-9|_|@]*)/);
    return m[1].toLowerCase();
}
 1
Author: Hans Petersen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-02 22:27:04

Ok, funciona cuando lo escribes de esta manera:

function debug()
  if(!window.console) { 
    window.console = {};
    console.log = function() { /* do something */ };
  }
  console.log.apply(console, arguments);
}

Comportamiento extraño... pero si lo escribes de esta manera ' consola.log ' se reconoce como una función.

 0
Author: line-o,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-04 13:34:58

La razón por la que llegué a esta pregunta fue que yo como tratando de 'picante' la consola.función de registro para un módulo específico, por lo que tendría información de depuración más localizada y perspicaz jugando un poco con los argumentos, es decir, 9 lo rompió.

@Andy E respuesta es genial y me ayudó con un montón de información acerca de aplicar. Simplemente no tomo el mismo enfoque para soportar IE9, por lo que mi solución está ejecutando la consola solo en " navegadores modernos "( siendo que moderno significa cualquier navegador que se comporten de la manera que espero =)

var C = function() {
  var args = Array.prototype.slice.call(arguments);
  var console = window.console;
  args[0]  = "Module X: "+args[0];
  if( typeof console == 'object' && console.log && console.log.apply ){
    console.log.apply(console, args);
  }
};
 0
Author: Fabiano Soriani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-21 19:42:21

Intenta:

function log(type) {
  if (typeof console !== 'undefined' && typeof console.log !== 'undefined' &&
    console[type] && Function.prototype.bind) {
    var log = Function.prototype.bind.call(console[type], console);
    log.apply(console, Array.prototype.slice.call(arguments, 1));
  }
}
log('info', 'test', 'pass');
log('error', 'test', 'fail');

Funciona para log, debug, info, warn, error, group o groupEnd.

 0
Author: Shobhit Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-03 14:33:12