閉包
// 坑
function count() {
var arr = [];
for (var i=1; i<=3; i++) { // 這里可以使用 let 聲明 i 來避免坑
arr.push(function () {
return i * i;
});
}
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
// 調用
f1(); // 16
f2(); // 16
f3(); // 16
由于返回的函數引用了變量i
,但它并非立刻執行。等到3個函數都返回時,它們所引用的變量i
已經變成了4,因此最終結果為16。
填坑:
再創建一個函數,用該函數的參數綁定循環變量當前的值,無論該循環變量后續如何更改,已綁定到函數參數的值不變:
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push((function (n) {
return function () {
return n * n;
}
})(i));
}
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
f1(); // 1
f2(); // 4
f3(); // 9
注意:創建立即執行函數需要用括號括起來:
(function (x) { return x * x }) (3);
,否則會報語法錯誤。
巧用閉包將多參數函數變成單參數函數
function make_pow(n) {
return function (x) {
return Math.pow(x, n);
}
}
// 創建兩個新函數:
var pow2 = make_pow(2);
var pow3 = make_pow(3);
pow2(5); // 25
pow3(7); // 343