console.log.apply not working in IE9

后端 未结 7 597
情深已故
情深已故 2020-11-29 00:32

Looks like I\'ve re-invented the wheel, but somehow this isn\'t working in Internet Explorer 9, but does in IE6.

function debug()
  if(!window.console) { 
           


        
相关标签:
7条回答
  • 2020-11-29 00:47

    There is also Paul Irish's way of doing it. It is simpler than some of the answers above, but makes log always output an array (even if only one argument was passed in):

    // 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) );
      }
    };
    
    0 讨论(0)
  • 2020-11-29 00:47

    Several of IE's host object functions aren't really JavaScript functions and so don't have apply or call. (alert, for example.)

    So you'll have to do it the hard way:

    function debug()
      var index;
    
      if(!window.console) { 
        window.console = { log: function() { /* do something */ } };
      }
      for (index = 0; index < arguments.length; ++index) {
          console.log(arguments[index]);
      }
    }
    
    0 讨论(0)
  • 2020-11-29 00:52

    Try:

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

    Works for log, debug, info, warn, error, group or groupEnd.

    0 讨论(0)
  • 2020-11-29 00:55

    The second part of an answer I gave recently answers this question too. I don't consider this a duplicate of that one so, for convenience, I'll paste it here:

    The console object is not part of any standard and is an extension to the Document Object Model. Like other DOM objects, it is considered a host object and is not required to inherit from Object, nor its methods from Function, like native ECMAScript functions and objects do. This is the reason apply and call are undefined on those methods. In IE 9, most DOM objects were improved to inherit from native ECMAScript types. As the developer tools are considered an extension to IE (albeit, a built-in extension), they clearly didn't receive the same improvements as the rest of the DOM.

    For what it's worth, you can still use some Function.prototype methods on console methods with a little bind() magic:

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

    So you could fix up all the console methods for IE 9 in the same manner:

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

    This replaces the "host" functions with native functions that call the "host" functions. You can get it working in Internet Explorer 8 by including the compatibility implementations for Function.prototype.bind and Array.prototype.forEach in your code, or rewriting the above snippet to incorporate the techniques used by those methods.

    See also

    • console.log typeof is "object" instead of "function" - Microsoft Connect (Live account required)
    0 讨论(0)
  • 2020-11-29 00:55

    Ok, it works when you write it this way:

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

    Odd behaviour... but if you write it this way 'console.log' gets recognized as a function.

    0 讨论(0)
  • 2020-11-29 01:02

    I came across the same IE trouble and made a routine for it. It is not as fancy as all the above implementations, but it works in ALL modern browsers.

    I tested it with Firefox (Firebug), IE 7,8,9 Chrome and Opera. It makes use of the evil EVAL, but you will only want to debug in development. Afterwards you will replace the code with debug = function () {};

    So here it is.

    Regards, 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 forgot my toType function, here it is.

    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();
    }
    
    0 讨论(0)
提交回复
热议问题