wake-up-neo.net

console.log.apply funktioniert nicht im IE9

Sieht aus, als hätte ich das Rad neu erfunden, aber irgendwie funktioniert das nicht in Internet Explorer 9, aber in IE6.

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

Verwandte: Apply () - Frage für Javascript

Der F12-Debugger sagt mir, dass dieses "Objekt" (console.log) die Methode 'apply' ..__ nicht unterstützt. Wird es nicht einmal als Funktion erkannt? Andere Hinweise oder Ideen?

46
line-o

Der zweite Teil einer Antwort habe ich kürzlich gegeben beantwortet auch diese Frage. Ich halte dies nicht für ein Duplikat, also füge ich es hier ein:

Das Konsolenobjekt ist kein Bestandteil eines Standards und ist eine Erweiterung des Document Object Model. Wie andere DOM-Objekte wird es als Host-Objekt betrachtet und muss weder von Object erben noch von seinen Methoden von Function, wie native ECMAScript-Funktionen und -Objekte. Dies ist der Grund, warum gelten und der Aufruf für diese Methoden undefiniert ist. In IE 9 wurden die meisten DOM-Objekte verbessert, um von nativen ECMAScript-Typen zu erben. Da die Entwicklertools als eine Erweiterung von IE (wenn auch als integrierte Erweiterung) betrachtet werden, haben sie offensichtlich nicht die gleichen Verbesserungen wie der Rest des DOM erhalten.

Für etwas, was es wert ist, können Sie trotzdem einige Function.prototype-Methoden mit etwas Bind () - Zauber auf Konsolenmethoden anwenden:

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

Sie können also alle console-Methoden für IE 9 auf dieselbe Weise anpassen:

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

Dies ersetzt die "Host" -Funktionen durch native Funktionen, die die "Host" -Funktionen aufrufen. Sie können es in Internet Explorer 8 zum Laufen bringen, indem Sie die Kompatibilitätsimplementierungen für Function.prototype.bind und Array.prototype.forEach in Ihren Code aufnehmen oder das obige Snippet umschreiben, um die von diesen Methoden verwendeten Techniken zu integrieren.

Siehe auch

92
Andy E

Es gibt auch Paul Irishs Art, dies zu tun. Es ist einfacher als einige der obigen Antworten, aber log gibt immer ein Array aus (auch wenn nur ein Argument übergeben wurde):

// 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
BishopZ

Einige Host-Objektfunktionen des IE sind keine eigentlichen JavaScript-Funktionen und haben daher keine apply oder call. (alert zum Beispiel.)

Also musst du es auf die harte Tour machen:

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
T.J. Crowder

Ich bin auf die gleichen IE Probleme gestoßen und habe eine Routine dafür gemacht ... __ Es ist nicht so schick wie alle obigen Implementierungen, aber es funktioniert in ALLEN modernen Browsern.

Ich habe es mit Firefox (Firebug), IE 7,8,9 Chrome und Opera ..__ getestet. Es nutzt das böse EVAL, aber Sie wollen nur in der Entwicklung debuggen . Danach Sie werden den Code durch debug = function () {}; ersetzen.

Hier ist es also.

Grüße, 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 hat meine toType-Funktion vergessen, hier ist sie.

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
Hans Petersen

Versuchen:

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

Funktioniert für log, debug, info, warn, error, group oder groupEnd.

0
Shobhit Sharma

Der Grund, weshalb ich zu dieser Frage kam, war, dass ich versuche, die console.log-Funktion für ein bestimmtes Modul zu "scharf" zu machen. Ich hätte also mehr lokalisierte und aufschlussreiche Debug-Informationen, indem ich mit den Argumenten ein wenig spielte. IE 9 hat es gebrochen.

@Andy E Antwort ist großartig und hat mir mit vielen Einsichten über die Bewerbung geholfen. Ich unterstütze IE9 nicht auf die gleiche Art und Weise, daher führt meine Lösung die Konsole nur auf "modernen Browsern" aus (dh, modern bedeutet, alle Browser, die sich so verhalten, wie ich es erwartet habe).

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
Fabiano Soriani

Ok, es funktioniert, wenn Sie es so schreiben:

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

Seltsames Verhalten ... aber wenn Sie es so schreiben, wird 'console.log' als Funktion erkannt.

0
line-o