假设我想在某些合法的生产原因中包含对console.log
的一些调用,比如像单元测试工具那样。显然,如果浏览器没有console
或no console is present,我不希望这会抛出过早的异常。
创建简单的log
函数以将内容记录到控制台的最佳方法是什么,或者如果没有控制台,则默默地失败而没有错误?
上述相关问题的接受答案:
var log = Function.prototype.bind.call(console.log, console); log.apply(console, ["this", "is", "a", "test"]);
这个log
函数是否可以在IE上正常调用,这里使用apply
只是为了表明它是可能的?并且,我从链接的问题中假设,如果IE的控制台在运行时关闭,这将失败,因此即使在控制台打开后,log
也无法工作,对吗?如果这是错的,有人可以解释它是如何工作的吗?
此ycombinator article似乎相关。他们是在讨论与上面链接的问题相同的IE行为吗?
Function.prototype.apply.apply(console.log, [console, arguments]);
适用于IE9破解的console.log和其他供应商的常规console.log。 与使用Array.prototype.slice将参数转换为实数组相同的黑客。
这在我的Chrome控制台中运行良好。
function echo(){
Function.prototype.apply.apply(console.log, [console, arguments]);
}
简化为:
function echo(){
Function.apply.call(console.log, console, arguments);
}
添加支票并返回:
function echo(){
return window.console && console.log &&
Function.apply.call(console.log, console, arguments);
}
上面的例子对我来说足够了。不过,我手头没有IE来测试它。这是安全包装console.log
的合理方法吗?
更多问题
按照以下导航答案中的链接,我们会看到代码:
Function.prototype.call.call(console.log, console,
Array.prototype.slice.call(arguments));
在这种情况下,将arguments
转换为数组的目的是什么?我想如果你不这样做,它必须在某些浏览器中失败?并且,除了歌剧奇怪的行为和无控制台的浏览器之外,这样的东西不应该适用于其他所有浏览器吗? prototype
是否有助于上述示例中的目的,或者我们只是迂腐...... Function.call.call
或Object.call.call
或者isNaN.call.call
似乎也很有用Function.prototype.call.call
为{{1}}。
答案 0 :(得分:20)
包装器的问题在于它们会混淆日志消息源的文件名和行号。
简单的IE7及以下垫片,为其他浏览器保留行号:
/* console shim*/
(function () {
var f = function () {};
if (!window.console) {
window.console = {
log:f, info:f, warn:f, debug:f, error:f
};
}
}());
答案 1 :(得分:16)
抱歉,我的帖子中有个错误。不知道我是怎么错过的。
创建全局控制台对象的正确方法(如果不存在):
if (typeof console === "undefined"){
console={};
console.log = function(){
return;
}
}
答案 2 :(得分:7)
这个日志功能可以在IE上正常调用,在这里使用apply只是为了表明它是可能的吗?
是的,是的。这个特定的例子直接针对“它是一个真正的函数”链接问题的一部分。
并且,我从链接的问题中假设,如果IE的控制台在运行时关闭,这将失败,因此即使在控制台打开后,日志也无法正常工作,对吗?
正确。正如我在该问题的答案中所解释的,console
对象在第一次为特定选项卡打开开发人员工具之前不会公开。大多数开发人员使用控制台垫片,在这种情况下,Function#bind
方法有点过时,因为您也可以使用Function#apply.apply
方法。
在这种情况下,将参数转换为数组的目的是什么?
没有一个,这是多余的。除非它是自定义 log 实现,否则开发人员可能有理由将参数对象转换为数组。
在上面的例子中原型是否有用,或者我们只是迂腐...
嗯,是的,不是。某些开发人员可能无意中将Function.call
更改为自定义函数或值。当然,他们也可以打破Function.prototype.call
,但这不太可能偶然发生。
答案 3 :(得分:6)
我喜欢使用:
'console' in window && console.log("Boom!");
它适用于所有浏览器,易于理解。
答案 4 :(得分:3)
尝试使用下面的代码段...(这是我首选的方法,因为它使您独立于window.console)
var logger = (function (c) {
"use strict";
var m = {
log: function (a, t) {
if (!c) { return; /* return or call your custom function here */ }
var l = c.log,
f = t === undefined ? l : (this.__dict__[t] || l);
f.apply(c, a)
},
__dict__: {
"trace": c.trace,
"debug": c.debug,
"info": c.info,
"warn": c.warn,
"error": c.error
}
};
return {
trace: function () { m.log(arguments, "trace"); },
debug: function () { m.log(arguments, "debug"); },
info: function () { m.log(arguments, "info"); },
warn: function () { m.log(arguments, "warn"); },
error: function () { m.log(arguments, "error"); },
log: function () { m.log(arguments, undefined); }
};
}(window.console))
因此,您现在可以在代码中尝试这些并查看结果
logger.info("Hello");
logger.trace("Hello");
logger.debug("Hello");
logger.warn("Hello");
logger.error("Hello");
logger.log("Hello");
答案 5 :(得分:1)
作为克里斯回答的一个细微变化,只需将'log'定义为具有空函数的'console'的属性:
if (typeof console === "undefined") {
console = {
log: function () {
return;
}
};
}
答案 6 :(得分:0)
Paul Irish有一个很好的光包装/替代console.log()
。
http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
优点:
log()
或window.log()
。答案 7 :(得分:0)
我可笑的过度设计的控制台:
console.log
语句console.error
,console.group
以及所有其他方法太棒了。
但实际上,您不应该在代码中留下console
个陈述。
答案 8 :(得分:0)
CoffeeScript的:
empty_function = ->
return
if !window.console?
window.console = {}
for fn in ['log', 'info', 'warn', 'debug', 'error']
if (typeof window.console[fn] isnt 'function')
window.console[fn] = empty_function
JS:
(function() {
var empty_function, fn, i, len, ref;
empty_function = function() {};
if (window.console == null) {
window.console = {};
ref = ['log', 'info', 'warn', 'debug', 'error'];
for (i = 0, len = ref.length; i < len; i++) {
fn = ref[i];
if (typeof window.console[fn] !== 'function') {
window.console[fn] = empty_function;
}
}
}
}).call(this);
答案 9 :(得分:-1)
我的解决方案有点不同。我为所有console.log调用创建了一个标准快捷方式:在我的情况下,kag(无论我想在控制台中报告什么)。
我测试IE,如果IE我将结果发送到警告框。如果Chrome随后显示在控制台中。这也意味着IE即使在控制台关闭时也会一直工作:
代码:
var iever = getInternetExplorerVersion();
if(iever>-1){
function kag(params){
alert(params);
}
} else {
var kag = console.log.bind(console, "REPORT: ");
}
function getInternetExplorerVersion() {
var rv = -1;
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null){
rv = parseFloat( RegExp.$1 );
}
}
return rv;
}