2011-07-06 458 views
2

在調試我發現,這樣的功能:匿名和命名的函數懷疑

var f = function() {}; 

對螢火蟲或webkits開發者控制檯中的堆棧跟蹤顯示爲anonymous,是理所當然的。

此外,我見過的人定義這些爲:

var someName = function otherName(){}; 

這是非常奇怪的。請注意,在這裏你不能撥打otherName()從任何地方otherName本身的身體。從其他地方你必須使用someName()

我的問題是:

  • 是否有命名在那裏的存儲從VAR不同功能的任何問題?

  • var a = function a(){}除了在堆棧跟蹤中顯示名稱之外,還有什麼區別嗎?

  • 關於這個主題:)

+1

Afaik,在某些IE版本(可能只有6個)中,命名函數表達式存在一些問題。它將爲這兩個名稱創建**兩個**實例(對於每個名稱)而不是一個。 –

回答

3

將名爲f的函數分配給名爲a的變量沒有任何問題。

功能的一個很好的參考是https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope。特別感興趣的是題爲「函數構造函數與函數聲明與函數表達式」的章節,詳細討論了函數名稱與函數賦值變量之間的區別。 (您可能已經看到了這一點。)

我的猜測是,調試器打印像

var a = function a() {} 

是,當函數值本身是序列化的函數的名字出現的原因。調試器給你所有的信息。

+0

打印名稱的調試器意味着放在'function'右側的名稱出現在堆棧跟蹤中。如果你什麼都不放,它只會顯示「匿名函數」,這是有道理的 –

+0

你完全正確。如果給函數一個名字,無論是通過函數聲明,還是通過將一個命名的函數表達式分配給一個變量,調試器都應該顯示它。函數具有(1)可選名稱,(2)零個或多個參數,以及(3)正文。由於該名稱是可選的,因此您的調試器將顯示該名稱,如果它具有一個名稱,則顯示該名稱,否則顯示該名稱。 –

+0

+1。它幾乎是我所需要的@Ray! –

0

不是真的任何其他提示/建議。使用var a = function b() {}命名的函數不會被掛起,其原型也不會被有意義地修改。看看下面的代碼,例如:

function foo() { 
} 
foo.prototype.bar = "hi"; 

var a = new foo();   // this inherits from function foo() above 
var b = function foo() {}; // this has nothing to do with the above 

console.log(a.bar); // returns "hi" due to inheritance 
console.log(b.bar); // returns undefined; its prototype is a new named 
        // function 

var c = function() {}; 
var d = function d() {}; 

console.log(c.name); // returns "" 
console.log(d.name); // returns "d" 

AFAICT,主要有用的方法是具有name方便(大多爲var a = function a(){}形式),這可能在一些邊緣情況有幫助的,我覺得主要是在錯誤處理。

+0

關於答案的最後部分,通過使'name'可訪問是什麼意思?如果函數未被命名,它如何不可訪問? –

+1

'var a = new foo();'和'var b = function foo(){};'是兩種不同類型的語句。比較它們是沒有意義的。 –

+0

@Pablo看我的編輯。我說'var foo = function(){}'的'name'是'''',但'var bar = function bar(){}'的'name'是'「bar」'。我相信你也注意到了這一點。我不認爲它很有用,只是說如果你想知道函數的名字,這就是你如何得到它。 – brymck