Javascript console.log.apply 在 IE9 中不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5538972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:43:02  来源:igfitidea点击:

console.log.apply not working in IE9

javascriptdebuggingconsoleinternet-explorer-9

提问by line-o

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

看起来我重新发明了轮子,但不知何故这在 Internet Explorer 9 中不起作用,但在 IE6 中起作用。

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

Related: Apply() question for javascript

相关: JavaScript 的 Apply() 问题

F12 Debugger tells me that this "object" (console.log) does not support method 'apply'. Is it not even recognized as a function? Any other pointers or ideas?

F12 调试器告诉我这个“对象”(console.log)不支持方法“apply”。它甚至不被识别为一个函数吗?任何其他指针或想法?

回答by Andy E

The second part of an answer I gave recentlyanswers 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"

控制台对象不是任何标准的一部分,而是文档对象模型的扩展。像其他 DOM 对象一样,它被认为是宿主对象,不需要从 Object 继承,也不需要从 Function 继承它的方法,就像原生的 ECMAScript 函数和对象那样。这就是在这些方法上未定义 apply 和 call 的原因。在 IE 9 中,大多数 DOM 对象都被改进为继承自原生 ECMAScript 类型。由于开发人员工具被认为是 IE 的扩展(尽管是内置扩展),因此它们显然没有像 DOM 的其余部分那样得到相同的改进。

对于它的价值,您仍然可以在控制台方法上使用一些 Function.prototype 方法,并带有一点 bind() 魔法:

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

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

因此,您可以以相同的方式修复IE 9 的所有console方法:

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.bindand Array.prototype.forEachin your code, or rewriting the above snippet to incorporate the techniques used by those methods.

这用调用“主机”函数的本机函数替换了“主机”函数。您可以通过兼容的实现为得到它在Internet Explorer 8的工作Function.prototype.bind,并Array.prototype.forEach在你的代码,或重写上面的代码中纳入由这些方法所使用的技术。

See also

也可以看看

回答by BishopZ

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):

还有保罗爱尔兰的做法。它比上面的一些答案更简单,但使 log 始终输出一个数组(即使只传入一个参数):

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

回答by T.J. Crowder

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

IE 的一些宿主对象函数并不是真正的 JavaScript 函数,因此没有applycall。(alert例如。)

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

回答by Hans Petersen

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.

我遇到了同样的 IE 问题,并为此做了一个例程。它不像上述所有实现那样花哨,但它适用于所有现代浏览器。

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

我用 Firefox (Firebug)、IE 7,8,9 Chrome 和 Opera 对其进行了测试。它利用了邪恶的 EVAL,但您只想在开发中进行调试。之后,您将代码替换为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.

哎呀忘了我的 toType 函数,它在这里。

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

回答by Shobhit Sharma

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, groupor groupEnd.

作品logdebuginfowarnerrorgroupgroupEnd

回答by line-o

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.

奇怪的行为……但是如果你这样写,'console.log' 就会被识别为一个函数。

回答by Fabiano Soriani

The reason I came to this question was that I as trying to 'spicy' the console.log function for a specific module, so I'd have more localized and insightful debug info by playing a bit with the arguments, IE 9 broke it.

我来到这个问题的原因是我试图为特定模块“辣”console.log 函数,所以我会通过稍微使用参数来获得更多本地化和有见地的调试信息,IE 9 打破了它。

@Andy E answer is great and helped me with lots of insight about apply. I just don't take the same approach to support IE9, so my solution is running the console only on "modern browsers" (being that modern means whatever browsers that behave the way I expect =)

@Andy E 的回答很棒,并帮助我获得了很多关于申请的见解。我只是不采用相同的方法来支持 IE9,因此我的解决方案仅在“现代浏览器”上运行控制台(现代意味着任何浏览器的行为都符合我的预期 =)

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