Javascript,for循环不起作用

Hid*_*dde 2 javascript arrays for-loop

var a=0;
setTimeout (function () { animatedDraw(context, 20+32*level[0],20*0, textArray[0]); }, timeArray[0]);
setTimeout (function () { animatedDraw(context, 20+32*level[1],20*1, textArray[1]); }, timeArray[1]);
setTimeout (function () { animatedDraw(context, 20+32*level[2],20*2, textArray[2]); }, timeArray[2]);
setTimeout (function () { animatedDraw(context, 20+32*level[3],20*3, textArray[3]); }, timeArray[3]);
setTimeout (function () { animatedDraw(context, 20+32*level[4],20*4, textArray[4]); }, timeArray[4]);
setTimeout (function () { animatedDraw(context, 20+32*level[5],20*5, textArray[5]); }, timeArray[5]);

for (a=0; a<6; a++)
    setTimeout (function () { animatedDraw(context, 20+32*level[a],20*0, textArray[a]); }, timeArray[a]);
Run Code Online (Sandbox Code Playgroud)

我的代码的第一部分是有效的部分.第二部分没有出现.我正在绘制画布(HTML 5),但当我弹出六个警告框时,警告框显示.我做的事情非常愚蠢吗?

提前致谢

T.J*_*der 12

原因是你所提供的函数setTimeout是闭包,闭包对它们所关闭的变量有持久的引用,而不是在创建闭包时它们的值的副本.因此,所有这些函数将尝试使用相同的值a,即循环完成的值(例如6),因此它们将失败.

答案是让函数接近其他一些数据而不会改变.通常的方法是使用一个工厂函数来创建并返回所需的实际函数,让它们接近你输入工厂函数的参数(不会改变),而不是你的循环变量.例如:

for (a=0; a<6; a++) {
    setTimeout(makeTimerFunction(a), timeArray[a]);
}

function makeTimerFunction(index) {
    return function () {
        animatedDraw(context, 20+32*level[index],20*0, textArray[index]);
    };
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,现在正被创建的功能makeTimerFunction被关闭了index,而不是a(并且还在context,leveltextArray,你会通过那些,以及如果他们改变).

关于闭包的更多信息:闭包并不复杂