2012-03-12 61 views
15

我見過其他人使用以下模式。爲什麼JavaScript函數聲明(和表達式)?

var bar = function foo(){}; 
console.log(bar); // foo() 
console.log(foo); // ReferenceError: foo is not defined 

但是爲什麼?如果兩者都被宣佈,我可以看到這一點,但他們不是。爲什麼是這個原因?

+3

你有什麼就有什麼,有一個名稱的匿名函數。我知道這樣做的唯一原因是當你調試到foo()函數時,堆棧跟蹤將顯示名稱而不是「匿名函數」。 – 2012-03-12 12:47:03

回答

7

正如其他人所提到的,使用第一種形式在您的示例(命名函數表達式)與調試幫助,但在內置的瀏覽器開發者工具,這種說法變得不那麼有說服力的最新改進。使用命名函數表達式的另一個原因是,您可以使用函數名稱作爲函數體內的變量,而不是現在在ES5 arguments.callee中棄用的變量。

但是,命名的函數表達式是不正確,並且在Internet Explorer中實現時出現問題,並且在針對這些瀏覽器時通常應該避免。有關更多信息,請參閱Juriy Zaytsev's excellent article on the subject

+0

用於提及內部作用域中函數名稱的可見性。 – fcalderan 2012-03-12 12:59:50

+0

+1,正如在Mozilla的官方文檔中看到的那樣''函數名稱只能在函數的主體中使用。「#:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#差異 – 2014-11-10 09:41:35

7

調試應用程序時,使用「named」匿名函數時,更容易知道調用堆棧中的內容是什麼。所以這是一種給匿名函數命名的方法,用於調試目的。

試試這個,看看調用堆棧在調試器:

myDiv = document.getElementById("myDiv"); 

myDiv.onclick = function OnClick(){ 
    debugger; 
    //do something 
} 
+1

我做了一個小提示,證明你的觀點:http://jsfiddle.net/fqeDG/。 謝謝! – 98374598347934875 2012-03-12 12:55:29

+4

小心在IE <9中使用命名函數表達式:這些瀏覽器中的實現被破壞。 http://kangax.github.com/nfe/ – 2012-03-12 13:01:27

+0

詳細說明,onclick屬性的函數分配在ie的早期版本中被打破,而不是語法函數OnClick(){}。 – Zoidberg 2012-03-12 14:36:40

2

,因爲它使調試更加方便它們命名匿名函數。調試時,您會在調用堆棧中看到對「foo」的調用,而不是一堆對「匿名」的調用。

2

我能想到的唯一原因就是給函數一個想要的名字。這有助於調試,因爲檢查員使用功能對象的name屬性。試試這個:

var bar = function foo(){}; 
console.log(bar.name); // foo 

如果你把裏面的foo的一些實際的代碼和一個斷點在瀏覽器中添加JavaScript調試器,你會看到的功能調用堆棧foo

0

函數定義(或文字)有4個部分。 1.保留字function 2.可選名稱,可由調試器或函數用於遞歸調用。 3.參數和4.函數主體包裝{ }

函數範圍foo之外不存在。但是由於您將函數分配給變量欄,因此您可以使用方法調用欄來調用它,並且由於已定義了欄,因此您可以將其打印出來。

如果您在JavaScript有興趣,你真的應該考慮讓Douglas Crockford's book Javascript: The Good Parts

相關問題