console.log.apply 在 IE9 中不起作用
Posted
技术标签:
【中文标题】console.log.apply 在 IE9 中不起作用【英文标题】:console.log.apply not working in IE9 【发布时间】:2011-07-29 04:19:25 【问题描述】:看起来我重新发明了***,但不知何故,这在 Internet Explorer 9 中不起作用,但在 IE6 中起作用。
function debug()
if(!window.console)
window.console = log: function() /* do something */ ;
console.log.apply(console, arguments);
相关: Apply() question for javascript
F12 调试器告诉我这个“对象”(console.log)不支持方法“应用”。 它甚至不被认为是一种功能吗? 还有其他的建议或想法吗?
【问题讨论】:
【参考方案1】:IE 的一些宿主对象函数并不是真正的 JavaScript 函数,因此没有 apply
或 call
。 (例如alert
。)
所以你必须努力做到这一点:
function debug()
var index;
if(!window.console)
window.console = log: function() /* do something */ ;
for (index = 0; index < arguments.length; ++index)
console.log(arguments[index]);
【讨论】:
没错。并非 JS 中所有可调用的东西都必须是Function
对象。
一开始我也是这么想的。但话又说回来,它之前没有定义。
@line-o:请注意,您在某些地方使用window.console
,而在其他地方使用console
。现在,在所有其他条件相同的情况下,这些应该会得出相同的结果,但这是我们正在谈论的 IE,如果它与 console.log
玩魔术游戏,我不会完全感到惊讶。
@Tim Down:是的,很像 RegExp 实例的非标准扩展,使它们可以调用。 @TJC,@line-o:console
对象在您第一次启动特定选项卡的开发人员工具之前不存在。【参考方案2】:
好的,这样写就可以了:
function debug()
if(!window.console)
window.console = ;
console.log = function() /* do something */ ;
console.log.apply(console, arguments);
奇怪的行为......但如果你这样写,'console.log' 会被识别为一个函数。
【讨论】:
查看我对您对我的回答的评论的回复。你的前后矛盾应该没问题,但我敢打赌 IE 正在玩愚蠢的游戏。【参考方案3】:答案I gave recently 的第二部分也回答了这个问题。我不认为这是一个副本,因此为方便起见,我将其粘贴在这里:
控制台对象不是任何标准的一部分,它是文档对象模型的扩展。与其他 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"
因此,您可以以相同的方式修复 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);
这用调用“主机”函数的本机函数替换了“主机”函数。您可以通过在代码中包含Function.prototype.bind
和Array.prototype.forEach
的兼容性实现,或者重写上面的sn-p 以结合这些方法使用的技术,让它在Internet Explorer 8 中运行。
另见
console.log
typeof is "object" instead of "function" - Microsoft Connect(需要真实帐户)
【讨论】:
+1 当然,该解决方案确实引入了一个新的依赖项:Function#bind
,它必须在尚未完全符合 ECMAScript5 规范的实现中提供...
其实是针对IE6的。但它给了我更深入的洞察力并回答了我的问题,这对我帮助很大。所以,非常感谢@Andy
非常感谢@Andy,我需要这个来让我的框架中的调试器在 MSIE 上工作。我已经在源代码中添加了学分,再次感谢!
执行此操作的简短方法是:function debug() Function.prototype.apply.call(console.log, console, arguments);
,这基本上就是 bind
-ing 代码所做的。
我希望我能不止一次地支持这个答案。令人惊讶的信息和帮助!谢谢!【参考方案4】:
还有 Paul Irish 的做法。它比上面的一些答案更简单,但是让 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) );
;
【讨论】:
感谢您提出他的好方法。【参考方案5】:我提出这个问题的原因是我试图对特定模块的 console.log 函数进行“刺激”,因此我可以通过使用 IE 9 的参数来获得更多本地化和有洞察力的调试信息把它弄坏了。
@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);
;
【讨论】:
【参考方案6】:我遇到了同样的 IE 问题,并为此制定了一个例程。 它不像上述所有实现那样花哨,但它适用于所有现代浏览器。
我使用 Firefox (Firebug)、IE 7、8、9 Chrome 和 Opera 对其进行了测试。
它利用了邪恶的 EVAL,但您只想在开发中进行调试。
之后您将代码替换为debug = function () ;
原来如此。
问候,汉斯
(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);
糟糕,忘记了我的 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();
【讨论】:
【参考方案7】:试试:
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');
适用于log
、debug
、info
、warn
、error
、group
或 groupEnd
。
【讨论】:
以上是关于console.log.apply 在 IE9 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
TypeError:console.log.apply 上的非法调用