天天看點

每天學點JavaScript程式設計--函數表達式函數表達式

函數表達式

 函數表達式的特征

 使用函數實作遞歸

 使用閉包定義私有變量

數表達式是 JavaScript 中的一個既強大又容易令人困惑的特性。第 5 章曾介紹過,定義函數的方式有兩種:

一種是函數聲明,
另一種就是函數表達式。

函數聲明的文法是這樣的:

function functionName(arg0, arg1, arg2) {
//函數體
}           

首先是 function 關鍵字,然後是函數的名字,這就是指定函數名的方式。Firefox、Safari、Chrome和 Opera

都給函數定義了一個非标準的 name 屬性,通過這個屬性可以通路到給函數指定的名字。

這個屬性的值永遠等于跟在 function 關鍵字後面的辨別符。

//隻在 Firefox、Safari、Chrome 和 Opera 有效

alert(functionName.name); //"functionName"

關于函數聲明,它的一個重要特征就是函數聲明提升(function declaration hoisting),意思是在執行代碼之前會先讀取函數聲明。這就意味着可以把函數聲明放在調用它的語句後面。

sayHi();
function sayHi(){
alert("Hi!");
}           

這個例子不會抛出錯誤,因為在代碼執行之前會先讀取函數聲明。

第二種建立函數的方式是使用函數表達式。函數表達式有幾種不同的文法形式。下面是最常見的一

種形式。

var functionName = function(arg0, arg1, arg2){
//函數體
};           

這種形式看起來好像是正常的變量指派語句,即建立一個函數并将它指派給變量 functionName。

這種情況下建立的函數叫做匿名函數(anonymous function),因為 function 關鍵字後面沒有辨別符。

(匿名函數有時候也叫拉姆達函數。)匿名函數的 name 屬性是空字元串。

函數表達式與其他表達式一樣,在使用前必須先指派。以下代碼會導緻錯誤。

sayHi(); //錯誤:函數還不存在
var sayHi = function(){
alert("Hi!");
};           
了解函數提升的關鍵,就是了解函數聲明與函數表達式之間的差別。

例如,執行以下代碼的結果可

能會讓人意想不到。

//不要這樣做!
if(condition){
function sayHi(){
alert("Hi!");
}
} else {
function sayHi(){
alert("Yo!");
}
}           

表面上看,以上代碼表示在 condition 為 true 時,使用一個 sayHi()的定義;否則,就使用另一個定義。

實際上,這在 ECMAScript 中屬于無效文法,JavaScript 引擎會嘗試修正錯誤,将其轉換為合理的狀态。但問題是浏覽器嘗試修正錯誤的做法并不一緻。大多數浏覽器會傳回第二個聲明,忽略condition;

Firefox 會在 condition 為 true 時傳回第一個聲明。是以這種使用方式很危險,不應該出現在你的代碼中。不過,如果是使用函數表達式,那就沒有什麼問題了。

//可以這樣做
var sayHi;
if(condition){
sayHi = function(){
alert("Hi!");
};
} else {
sayHi = function(){
alert("Yo!");
};
}           

這個例子不會有什麼a意外,不同的函數會根據 condition 被指派給 sayHi。

能夠建立函數再指派給變量,也就能夠把函數作為其他函數的值傳回。還記得第 5 章中的那個

createComparisonFunction()函數嗎:

function createComparisonFunction(propertyName) {

return function(object1, object2){

var value1 = object1[propertyName];

var value2 = object2[propertyName];

圖靈社群會員 StinkBC([email protected]) 專享 尊重版權

繼續閱讀