// 下面2個括弧()都會立即執行
(function () { /* code */ } ()); // 推薦使用這個
(function () { /* code */ })(); // 但是這個也是可以用的
和普通function執行的時候傳參數一樣,自執行的函數表達式也可以這么傳參,因為閉包直接可以引用傳入的這些參數,利用這些被lock住的傳入參數,自執行函數表達式可以有效地保存狀態。
// 這個代碼是錯誤的,因為變量i從來就沒背locked住
// 相反,當循環執行以后,我們在點擊的時候i才獲得數值
// 因為這個時候i操真正獲得值
// 所以說無論點擊那個連接,最終顯示的都是I am link #10(如果有10個a元素的話)
var elems = document.getElementsByTagName('a');
for (var i = 0; i < elems.length; i++) {
elems[i].addEventListener('click', function (e) {
e.preventDefault();
alert('I am link #' + i);
}, 'false');
}
// 這個是可以用的,因為他在自執行函數表達式閉包內部
// i的值作為locked的索引存在,在循環執行結束以后,盡管最后i的值變成了a元素總數(例如10)
// 但閉包內部的lockedInIndex值是沒有改變,因為他已經執行完畢了
// 所以當點擊連接的時候,結果是正確的
var elems = document.getElementsByTagName('a');
for (var i = 0; i < elems.length; i++) {
(function (lockedInIndex) {
elems[i].addEventListener('click', function (e) {
e.preventDefault();
alert('I am link #' + lockedInIndex);
}, 'false');
})(i);
}
// 你也可以像下面這樣應用,在處理函數那里使用自執行函數表達式
// 而不是在addEventListener外部
// 但是相對來說,上面的代碼更具可讀性
var elems = document.getElementsByTagName('a');
for (var i = 0; i < elems.length; i++) {
elems[i].addEventListener('click', (function (lockedInIndex) {
return function (e) {
e.preventDefault();
alert('I am link #' + lockedInIndex);
};
})(i), 'false');
}