为什么';JavaScript函数别名是否有效?

为什么';JavaScript函数别名是否有效?,javascript,function,google-chrome,firebug,alias,Javascript,Function,Google Chrome,Firebug,Alias,我有一些Firebug控制台函数调用,我想在Firebug未启用时禁用,例如控制台未定义。这在IE6和FF3中运行良好,但在Chrome中不起作用: var log; if(console){ log = console.log; }else{ log = function(){ return; } } 我在Chrome中得到一个“未捕获的TypeError:非法调用”=/ 我读到关于这个问题,你必须应用一个上下文,这对我来说是新的。。。我似乎不知道如何在所有浏览器中实现上述功能…是

我有一些Firebug控制台函数调用,我想在Firebug未启用时禁用,例如控制台未定义。这在IE6和FF3中运行良好,但在Chrome中不起作用:

var log;

if(console){
  log = console.log;
}else{
  log = function(){ return; }
}
我在Chrome中得到一个“未捕获的TypeError:非法调用”=/


我读到关于这个问题,你必须应用一个上下文,这对我来说是新的。。。我似乎不知道如何在所有浏览器中实现上述功能…

是的,您应该保持上下文:

var log;

if (window.console && typeof console.log === "function"){
  // use apply to preserve context and invocations with multiple arguments
  log = function () { console.log.apply(console, arguments); };
} else {
  log = function(){ return; }
}
所发生的情况是,当您调用函数时,上下文(该值)被隐式设置,例如:

var obj = {
  method: function () { return this; }
};

obj.method() === obj; // true
在这种情况下,您正在调用一个定义为对象属性的函数,当调用该函数时,
this
值设置为该对象

现在,如示例所示,如果将该方法的引用复制到变量:

var method = obj.method;
method() === window; // global object
如您所见,
值指的是全局对象

因此,为了避免这种隐式行为,可以使用或函数显式设置上下文。

这不起作用:

log("hi");
虽然这样做:

log.call(console, "hi");
很明显,您需要使用正确的上下文调用别名函数——正如您自己所提到的

我认为您必须使用函数包装器(一个引用原始上下文的闭包)而不是别名

更新 还要注意,如果直接检查
控制台
,当变量不存在时,可能会出现运行时错误。最好在
window.console
中明确地检查它。这里有一种实现条件
log
包装器的方法:

var log = (function (console) {
    return console
        ? function () { console.log.apply(console, arguments); }
        : function () {}
})(window.console);

此解决方案修改了IE8的早期优秀答案。在执行此操作之前,您需要打开IE8控制台(按F12)。(如果忘记了,则需要完全退出IE8并重新启动,因为即使控制台存在,IE8也不会随后创建控制台对象。)

请注意,我们没有设置上下文,这是最初的问题,但事实证明,IE8不需要该上下文。(这是件好事,因为IE8也没有在控制台.log对象上提供apply方法!)

此代码适用于最新版本的Chrome、FireFox和MSIE。(它与MSIE6兼容,不会引发错误。)


在函数中包装函数(如console.log)的问题在于它会丢失上下文,即它不会显示我们放入“log”快捷方式的文件的正确行号

相反,我建议这样做:

 window.log = ((window.console && window.console.log) ?
              console.log.bind(console) : 
              function(){});
这适用于firebug和chrome开发工具,在没有可用控制台时不会抛出错误。最重要的是,显示了正确的文件和行号。

我这样做了

var log;

log = function() {
  if ((window.console != null) && (window.console.log.apply != null)) {
    return console.log.apply(console, arguments);
  } else {
    return function() {};
  }
};

if(console)
如果未为浏览器定义或禁用,将导致“console未定义”错误。你最好检查
(window.console)
或者甚至
(typeof console!=“undefined)”
@Ates,是的,如果
console
没有定义,
如果(window.console&&typeof console.log==“function”)
它更安全,经过编辑。是的,我会检查typeof,我只是简化了一下,因为这真的不是问题。值得一提的是,控制台不仅由FireBug定义,而且还存在于IE8和Chrome中。有趣的故事,我完全理解所有这些有趣的东西。我应该注意,这个问题增强了我对javascript的理解!伟大的唯一的答案是保留行号。我已经搜索了几个小时,试图找到一种方法来做到这一点,并保留控制台的文件名和行号。这很好用!
var log;

log = function() {
  if ((window.console != null) && (window.console.log.apply != null)) {
    return console.log.apply(console, arguments);
  } else {
    return function() {};
  }
};