问题描述
首先我们先来欣赏一段代码
function test() {
var arr = [];
for(var i = 0; i < 10; i ++){
arr[i] = function (){
document.write(i + " ");
}
}
return arr;
}
var Myarr = test();
for(var j = 0; j < 10; j ++){
Myarr[j]();
}
我们首先定义了一个test函数,然后在这个函数里面定义了一个数组,再通过for循环给数组里面的每一位变成一个函数,作用就是打印当前i的值。再然后return这个数组,最后在test函数外部定义Myarr,就等于test函数的执行结果,最后再执行Myarr数组的每一位。按之前的理解是执行的结果应该是0-9十个数字。但是实际结果是十个10.
解决方案
我们先来分析,为什么会打印出10,按道理说应该是9。问题就在于第一个for循环,i从1执行到了9,此时又重新开始一次循环,此时9<10,所以i就变成10了。但是此时i不满足for循环了,所以不执行里面的函数了。我们可以用以下代码解释
for(var i = 0; i < 10 ; i ++){
document.write(i)
}
document.write(i)
我们再来看为什么会输出10个10呢。这个问题在于arr[i] = function(){document.write(i + " ")。代码在执行for循环的时候,前面i的值发生变化,但是在后面的这个function里面的i并不会发生变化,因为在循环的时候这个function只是一个赋值语句,它并不会去看里面的内容,只有在最后调用Myarr的时候在来看里面的内容,而此时i的值已经全部循环结束变成10了。那我们要是想要它输出0-9十个数字怎么办呢?
此时闭包已经形成了,闭包也分好的和不好的,出现这种情况就属于不好的。那么我们要怎么去避免呢。我们想要的就是for循环里面的function里的i能够跟随外面的i一起变化。此时我们可以采用立即执行函数,完整代码如下
<script>
function test() {
var arr = [];
for(var i = 0; i < 10; i ++){
(function (j) {
arr [j] = function () {
document.write(j + " ");
}
}(i));
}
return arr;
}
var Myarr = test();
for(var j = 0; j < 10; j ++){
Myarr[j]();
}
</script>
END主 编 | 张祯悦
责 编 | 刘玉江
where2go 团队
微信号:算法与编程之美
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。