i am not the one you ever knew——java的循环与闭包

var printActions = new Array();
for(var i = 0; i < 10; i++) {
    printActions.push(function() {
        console.log(i);
    });
}
for(var i = 0; i < printActions.length; i++) {
    printActions[i]();
}

上面的代码执行的结果,相信了解java中的闭包的同学就知道是:

10
10
10
10
10
10
10
10
10
10

但是答案是:

0
1
2
3
4
5
6
7
8
9

这是为什么呢?

因为在第二个循环中i的值又被覆盖了。也就是说,javascript的变量求值是惰性的,只是根据变量名而在当前的context中求值。

for(var j = 0; j < printActions.length; j++) {
	printActions[j]();
}

这样子就看到10个10了。

为了避免这样的问题,我们应该"保护现场",javascript中的一个惯用做法是:

for(var i = 0; i < 10; i++) {
	(function(i) {
	    printActions.push(function() {
	        console.log(i);
	    });
	})(i);
}

这里的console.log(i)的i事实上已经是被求值了的,而不是一个依赖于context的变量。你可以将匿名函数的参数名变成其他的就能比较理解这一点。

原文地址:https://www.cnblogs.com/zhengwenwei/p/2687574.html