導言
在這篇文章中,我們將更詳細的討論一個常見的ECMAScript對象——函數。我們將詳細地研究函數的各種類型,解釋這種或那種類型的函數如何影響一個上下文的變量對象以及函數某一個類型的作用域鏈中包含什么。我們將回答論壇中像這樣經常被問及的問題:“下面創建的函數與以一種“習慣的方式”定義的函數之間有什么區別(如果有,是什么?)”(注:原文的順序不是這樣,本人作了調整)
var foo = function () { ...};
以一種“習慣的方式”定義的函數:
function foo() { ...}
或者,“為什么下面的函數調用應該用圓括號包圍?”
(function () { ...})();
因為這些文章獨立于早期的章節,由于我們會積極地使用來自這些章節的語法,為了全面理解這一部分,如有必要,值得去讀第二章:變量對象和第四章:作用域鏈。
但是讓我們一個個接著來,首先從函數的類型研究起。
函數類型
在ECMAScript 中有三種函數類型,每一種都有自己的特點。
函數聲明
函數聲明(縮寫為FD)是這樣一種函數:
function exampleFunc() { ...}
這種函數類型的主要特點在于它們僅僅影響變量對象(即函數存儲在上下文的VO中)。該特點也解釋了第二個重要點(它是變量對象特性的結果)——在代碼執行階段它們已經可用(因為FD在進入上下文階段已被VO收集)。
例如(源碼中函數在其聲明之前被調用)
foo();function foo() { alert('foo');}
同樣一個重要點是定義中的第二點——源碼中函數聲明的位置:
// function declaration// is directly in:// either the global context// at Program levelfunction globalFD() { // or directly inside the body // of another function function innerFD() {}}
在代碼中的任何其他位置,函數聲明不能出現——即,不可能在表達式位置或一個代碼塊中定義它。
取代函數聲明(更有可能認為是與之相對)的是函數表達式。