为什么JavaScript函数别名不起作用?

时间:2010-04-16 15:03:05

标签: javascript function google-chrome firebug alias

我有一些Firebug控制台函数调用,我想在Firebug未启用时禁用,例如控制台未定义。这适用于IE6和FF3,但不适用于Chrome:

var log;

if(console){
  log = console.log;
}else{
  log = function(){ return; }
}

我在Chrome中获得了“未捕获的TypeError:非法调用”= /

我读到了问题here,你必须应用一个上下文,这对我来说是一种新的......我似乎无法想象如何在所有浏览器中完成上述操作。

5 个答案:

答案 0 :(得分:27)

是的,你应该坚持上下文:

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

当您调用函数时,会隐式设置上下文(this值),例如:

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

obj.method() === obj; // true

在这种情况下,您正在调用一个被定义为对象属性的函数,当调用该函数时,this值被设置为该对象。

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

var method = obj.method;
method() === window; // global object

如您所见,this值指的是全局对象。

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

答案 1 :(得分:6)

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

相反,我建议这样的事情:

 window.log = ((window.console && window.console.log) ?
              console.log.bind(console) : 
              function(){});

这适用于firebug& chrome dev工具,当没有可用的控制台时不会抛出错误。并且 - 最重要的是 - 显示正确的文件和行号。

答案 2 :(得分:2)

这不起作用:

log("hi");

虽然这样做:

log.call(console, "hi");

很明显,您需要使用正确的上下文调用别名函数 - 正如您自己提到的那样。

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

更新

另请注意,如果直接检查console,则在变量不存在时可能会出现运行时错误。你最好明确地将它作为window.console进行检查。这是实现条件log包装器的一种方法:

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

答案 3 :(得分:1)

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

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

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

if((typeof console !== "undefined") && ((typeof console.log) !== "undefined"))
{
  if ((typeof console.log.apply !== "undefined"))
  {
    log = function() { console.log.apply(console,arguments) };
  }
  else
  {
    log = console.log;
  }
}
else
{
  log = function() {};
  // alert("No debug console");
}

答案 4 :(得分:0)

我做了这个

var log;

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