廖雪峰《JavaScript教程》 闭包
http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/00143449934543461c9d5dfeeb848f5b72bd012e1113d15000
以下两例均为教程中示例的引申。
例一:
var f1, a = [1, 2, 3, 4];
function lazy_sum(arr) {
return function() {
return arr.reduce(function(x, y) {
return x + y;
});
}
}
f1 = lazy_sum(a);
alert(f1()); //10
a[0] = 0;
alert(f1()); //9, not 10
闭包就是携带(绑定)状态的函数。这个例子中,return 的闭包函数体中引用了外部函数级变量arr,它携带的状态就是arr 所映射的实体,对于可变变量,更新数组a中元素,引起实体变化,闭包运行结果随之变化。
例二:
function count1() {
var arr = [];
for (var i = 1; i <= 3; i ++) {
arr.push(function () {
return i * i;
});
}
return arr;
}
var arr1 = count1();
var f1 = arr1[0]
alert(f1()) //16
function count2() {
var arr = [];
for (let i = 1; i <= 3; i ++) {
arr.push(function () {
return i * i;
});
}
return arr;
}
var arr2 = count2();
var f2 = arr2[0]
alert(f2()) //1
function count3() {
var arr = [];
for (var i = 1; i <= 3; i ++) {
arr.push((function (i) {
return function () {
return i * i;
}
})(i));
}
return arr;
}
var arr3 = count3();
var f3 = arr3[0];
alert(f3()); //1
count1 中闭包绑定的i 是count1 的函数级变量。
count2 中闭包绑定的i 是块级变量(let),每次块结束这个变量就固定下来了。
count3 中闭包绑定的i 是闭包的上层函数的函数级变量,互不想干。