问题描述
|
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],textArray[a]); },timeArray[a]);
我的代码的第一部分是起作用的部分。第二部分不显示。我正在画布上绘画(HTML 5),但是当我弹出六个警报框时,将显示警告框。
我在做一些非常愚蠢的错误吗?
提前致谢
解决方法
原因是您要输入到“ 1”的函数是闭包,并且闭包持久引用了其关闭的变量,而不是创建闭包时的值副本。因此,所有这些函数都将尝试使用相同的
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]);
};
}
如您所见,现在由makeTimerFunction
创建的函数将关闭index
而不是ѭ2closing(以及context
,level
和textArray
;如果它们发生变化,您也将其传入)。
有关闭包的更多信息:闭包并不复杂
, 这是非常常见的Javascript关闭问题。
循环中的变量a
在循环中继续更改,因此回调中使用的值将是它拥有的最后一个值,而不是每次循环中碰巧拥有的值。
最简单的解决方法是:
function timer_setup(a) {
setTimeout(function () {
animatedDraw(context,20+32*level[a],textArray[a]);
},timeArray[a]);
};
for (a=0; a<6; a++) {
timer_setup(a);
}
, 尝试这个...
for (a=0; a<6; a++)
{
(function(index)
{
setTimeout (function () { animatedDraw(context,textArray[index]); },timeArray[index]);
})(a)
}