簡體   English   中英

為什么JavaScript函數別名不起作用?

[英]Why doesn't JavaScript function aliasing work?

我有一些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; }
}

發生的事情是在調用函數時隱式設置上下文( this值),例如:

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

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

在這種情況下,您正在調用一個被定義為對象屬性的函數,當調用該函數時, this值被設置為該對象。

現在,如您的示例中所示,如果將該方法的引用復制到變量:

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

如您所見, this值指的是全局對象。

因此,為了避免這種隱式行為,您可以使用callapply函數顯式設置上下文。

在函數中包裝函數(如console.log)的問題是它丟失了它的上下文,即它不會顯示我們將“log”快捷方式放入的文件的正確行號。

相反,我建議這樣的事情:

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

這適用於firebug和chrome dev工具,並且在沒有可用的控制台時不會拋出錯誤。 並且 - 最重要的是 - 顯示正確的文件和行號。

這不起作用:

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

此解決方案修改了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");
}

我這樣做了

var log;

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM