天天看點

JavaScript裡的一等公民——函數

函數表聲明

function test(){
           alert("haha haha");
}      

這個函數名test可以用于引用和調用

函數表達式

var ask = function(){
  ...
}      

它不同于函數聲明有名稱,函數表達式是沒有名稱的。該表達式的結果是一個值,這個值被賦給了變量 ask。這個變量是一個指向函數的引用。

無論是函數表達式還是函數聲明,得到的都是函數。

看起來函數表達式和函數聲明沒有什麼差別,實際上浏覽器對待它們卻是有差別的。

差別1:

用函數聲明時,函數聲明将在執行代碼前建立,而使用函數表達式時,函數将在運作階段執行代碼時建立。

差別2:

與函數命名有關,使用函數聲明時,将建立一個與函數名同名的變量,并讓它指向函數;而使用函數表達式時,通常不用給函數指定名稱,是以要麼在代碼中将函數賦給一個變量 ,要麼以其他方式使用函數表達式。

函數表達式和其他表達式一樣,可以出現在很多不同的地方。在JavaScript中,函數是值,可以賦給變量的值,如同數字、字元串、布爾值、對象一樣,可以像它們一樣把函數值傳給函數或從函數傳回函數值,甚至将函數值存儲在對象或數組中。函數值不同之處在于,我們可以調用它。計算機科學家給這類型的值起了個術語名——一等值。

對于一等值可以做的事,包括:

(1)将其賦給變量或存儲在對象和數組等資料結構中。

(2)将其傳遞給函數。

(3)從函數中傳回它們。

函數值、數字、字元串、布爾值、對象等這些在JavaScript中都是一等值。

看看浏覽器是如何分析網頁的:

分析的過程
在分析網頁期間(執行任何代碼之前),浏覽器從頭到尾查找函數聲明,找到函數聲明時,浏覽器将建立相應的函數,然後将函數存儲起來,以便能夠在它被調用時擷取它,并建立一個與函數名同名的變量 ,然後将得到的函數引用賦給該變量;
處理完所有的函數聲明後,浏覽器回到代碼開頭,開始按從頭到尾的順序執行代碼。
如果遇到簡單的變量指派語句,浏覽器就會建立變量并初始化它。
如果遇到一個變量,它的右邊是函數表達式,那麼浏覽器會先建立這個變量,而右邊的函數将會被存儲起來,以便能夠在其被調用時擷取它,然後建立一個指向該函數的引用,并将這個引用賦給該變量。
如果再遇到函數聲明它就會跳過,因為前面已處理過了。
  1. 在處理其他代碼之前,先處理函數聲明。
  2. 函數聲明不傳回指向函數的引用,而是建立一個與函數同名的變量 ,并将指向函數的引用賦給它。
  3. 函數表達式傳回一個引用,該引用指向函數表達式建立的函數。
  4. 可以在變量中存儲指向函數的引用。
  5. 函數聲明是完整的語句,而函數表達式隻是語句的一部分。
  6. 對于函數聲明和函數表達式建立的函數,用相同的方式處理調用它們的語句。
  7. 建議盡可能使用函數聲明,因為它們首先被處理。