function test(){
var arr = [];
for(var i=0;i<10;i++){
arr[i] = function (){
console.log(i + ' ');
}
}
return arr;
}
var demo = test();
for(var i = 0;i<10;i++){
demo[i]();
}
上面是一道经典的闭包问题。
以上打印结果是10,10,10,10,10,10,10,10,10,10;
理解过程:
test()执行的时候会产生:test的AO和GO;
arr[0]、arr[1]、arr[2]、arr[3]、arr[4]、arr[5]、arr[6]、arr[7]、arr[8]、arr[9]、i==10的时候退出for循环,此时的 i = 10;最后返回arr;
arr[0]、.......arr[9]都拥有同一个test的AO和GO;且AO中的 i = 10;
最后执行便是打印10 次 10。
解决方案:
function test(){
var arr = [];
for(var i=0;i<10;i++){
(function (j){
arr[j] = function (){
console.log(j + ' ');
}
}(i))
}
return arr;
}
var demo = test();
for(var i = 0;i<10;i++){
demo[i]();
}
在理解上面这个方法前,先看一下下面这个方法;
function test(){
var arr = [];
for(var i=0;i<10;i++){
function a(j){
arr[j] = function (){
console.log(j + ' ');
}
}
a(i);
}
return arr;
}
var demo = test();
for(var i = 0;i<10;i++){
demo[i]();
}
立即执行函数被修改成了普通函数并执行,就更容易理解了;
执行test函数时:
当 i == 0 时:执行a, 此时有a的A(其中 j = 0) ,test的AO和GO ,执行完成后a函数会被销毁, 然而a的AO依然存在arr[0]中;
当 i == 1 时:执行a, 此时有a的A(其中 j = 1) ,test的AO和GO ,执行完成后a函数会被销毁, 然而a的AO依然存在arr[1]中;
当 i == 2 时:执行a, 此时有a的A(其中 j = 2) ,test的AO和GO ,执行完成后a函数会被销毁, 然而a的AO依然存在arr[2]中;
.......
当 i == 9 时:执行a, 此时有a的A(其中 j = 9) ,test的AO和GO ,执行完成后a函数会被销毁, 然而a的AO依然存在arr[9]中;
最后被保存在arr中被返回到test函数外部;