闭包
// 坑
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