http://www.cnblogs.com/fengmiaosen/archive/2011/01/10/1932403.html
使用在“360全景瀏覽”
在C/C++中,由花括號封閉的代碼塊都有自己的作用域,也就是塊級作用域(私有作用域)。而在javascript中則沒有塊級作用域,首先來看一段代碼:
}
alert(i);
執行結果是:
對於有塊級作用域的語言來說,for語句中定義並初始化的變量i在循環外是無法訪問的,而在javascript中,for語句中定義的變量i在循環結束後,依舊會存在於循環外部的執行環境(作用域)中,在這裏i的作用域是全局環境。具體來說就是:使用var關鍵字聲明變量時,這個變量會自動添加到距離最近的可用環境中。對於函數而言,這個最近的環境就是函數的局部環境。如果變量在未經聲明的情況下被初始化,則該變量會被自動添加到全局環境。
不過有時候的確很需要塊級作用域來解決一些問題,這時候我們就可以使用匿名函數來模仿塊級作用域。
匿名函數就是沒有名字的函數,有時候也被稱爲拉姆達(lamda)函數。形式如下:
}
而用作模仿塊級作用域(私有作用域)的匿名函數的語法形式如下:
//塊級作用域
})();
以上代碼的意思是:首先定義並立即調用一個匿名函數。將函數聲明包含在圓括號中,表示它實際上是一個函數表達式。而緊隨其後的另一對圓括號表示立即調用這個函數。
可能剛開始我們感覺這種語法比較難以理解,我們可以先看下下面這段代碼:
alert(‘函數’);
};
myFunc();
上面的代碼中,首先以函數表達式的方式定義了一個函數,然後立即調用它。在這裏定義函數的方式就是先創建一個匿名函數,然後將其賦值給變量myFunc,而在函數名稱後加一對圓括號即表示調用函數。那我們如果直接用匿名函數代表變量myFunc,在匿名函數後面添加一對圓括號不就表示直接調用了嗎?然而,如果如下這樣做就會報錯:
//塊級作用域
}();
因爲在javascript中,function關鍵字表示一個函數聲明的開始,而函數聲明後面不能直接跟圓括號。而函數表達式後面可以跟圓括號,來表示函數調用。在函數聲明外面加一對圓括號就可以轉換成函數表達式,如下:
//塊級作用域
})();
這樣最簡單的塊級作用域就創建好了。這種技術長在全局作用域中用在函數外部,來限制向全局作用域中添加過多的變量和函數。例如:
var now=new Date();
if(now.getMonth()==0&&now.getDate()==1){
alert(“Happy new year”);
}
})();
以上代碼放在全局作用域中,用來確定在1月1日顯示一條祝賀新年的信息。其中變量now現在就是匿名函數模仿的塊級作用域中的局部變量。
當然,只要我們臨時需要一些變量,都可以使用塊級作用域(私有作用域)。當匿名函數執行完畢,其作用域鏈立即銷燬,從而可以減少閉包占用資源問題。