console.log.apply non funziona in IE9

Sembra che abbia re-inventato la ruota, ma in qualche modo non funziona in Internet Explorer 9, ma in IE6.

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

Correlato: domanda () domanda per javascript

F12 Debugger mi dice che questo “object” (console.log) non supporta il metodo ‘apply’. Non è nemmeno riconosciuto come una funzione? Qualche altra indicazione o idea?

La seconda parte di una risposta che ho dato di recente risponde anche a questa domanda. Non considero questo un duplicato di quello quindi, per comodità, lo incollo qui:

L’object console non fa parte di alcuno standard ed è un’estensione del modello di object documento. Come altri oggetti DOM, è considerato un object host e non è necessario ereditare da Object, né i suoi metodi da Function, come fanno le funzioni e gli oggetti nativi di ECMAScript. Questa è la ragione per cui si applicano e le chiamate non sono definite su questi metodi. In IE 9, la maggior parte degli oggetti DOM è stata migliorata per ereditare dai tipi nativi di ECMAScript. Poiché gli strumenti di sviluppo sono considerati un’estensione di IE (anche se un’estensione built-in), chiaramente non hanno ricevuto gli stessi miglioramenti del resto del DOM.

Per quel che vale, puoi comunque usare alcuni metodi Function.prototype sui metodi di console con un po ‘di bind ():

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

Quindi è ansible correggere tutti i metodi di console per IE 9 nello stesso modo:

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

Questo sostituisce le funzioni “host” con funzioni native che chiamano le funzioni “host”. Puoi farlo funzionare in Internet Explorer 8 includendo le implementazioni di compatibilità per Function.prototype.bind e Array.prototype.forEach nel tuo codice, o riscrivendo lo snippet sopra riportato per incorporare le tecniche utilizzate da quei metodi.

Guarda anche

  • L’object problematico della console di Internet Explorer 9 – il mio blog, whattheheadsaid.com
  • console.log typeof è “object” anziché “function” – Microsoft Connect (è richiesto un account Live)

C’è anche il modo in cui Paul Irish lo fa. È più semplice di alcune delle risposte precedenti, ma fa sì che il log emetta sempre un array (anche se è stato passato solo un argomento):

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

Molte delle funzioni dell’object host di IE non sono realmente funzioni di JavaScript e quindi non hanno apply o call . ( alert , per esempio.)

Quindi dovrai farlo nel modo più duro:

 function debug() var index; if(!window.console) { window.console = { log: function() { /* do something */ } }; } for (index = 0; index < arguments.length; ++index) { console.log(arguments[index]); } } 

Mi sono imbattuto nello stesso problema di IE e ho fatto una routine per questo. Non è di fantasia come tutte le implementazioni di cui sopra, ma funziona in TUTTI i browser moderni.

L’ho provato con Firefox (Firebug), IE 7,8,9 Chrome e Opera. Fa uso del malvagio EVAL, ma vorrete fare il debug in sviluppo. Successivamente sostituirai il codice con debug = function () {};

Quindi eccolo qui.

Saluti, Hans

 (function(ns) { var msgs = []; // IE compatiblity function argtoarr (args,from) { var a = []; for (var i = from || 0; i0) log(msgs.shift()); } })(window); 

Oops ha dimenticato la mia funzione toType, eccola qui.

 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*([az|AZ|0-9|_|@]*)/); return m[1].toLowerCase(); } 

Ok, funziona quando lo scrivi in ​​questo modo:

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

Comportamento strano … ma se lo scrivi in ​​questo modo ‘console.log’ viene riconosciuto come una funzione.

La ragione per cui sono venuto a questa domanda è stata che cercavo di “speziare” la funzione console.log per un modulo specifico, quindi avrei avuto informazioni di debug più localizzate e intuitive giocando un po ‘con gli argomenti, IE 9 l’ha rotto.

@Andy E risposta è grande e mi ha aiutato con un sacco di informazioni su applicare. Io non prendo lo stesso approccio per supportare IE9, quindi la mia soluzione è eseguire la console solo su “browser moderni” (essendo quello moderno significa qualunque browser che si comporta come me lo aspetti =)

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

Provare:

 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'); 

Funziona per log , debug , info , warn , error , group o groupEnd .