Причина в том, что функции, которые вы вводите в setTimeout
, являются замыканиями, а замыкания имеют устойчивую ссылку на переменные, которые они закрывают, а не копию их значения по состоянию на момент создания закрытия. Следовательно, все эти функции будут пытаться использовать одно и то же значение a
, значение, которое оно имеет после , когда цикл завершен (например, 6), и поэтому они потерпят неудачу.
Ответ заключается в том, чтобы функции закрывали некоторые другие данные, которые не будут меняться. Обычный способ сделать это состоит в том, чтобы иметь фабричную функцию, которая создает и возвращает фактические функции, которые вы хотите, закрывая их по аргументу, который вы вводите в фабричную функцию (которая не изменится), а не по переменной цикла. E.g.:
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
, а не a
(а также по context
, level
и textArray
; вы пропустите эти в том числе, если они изменятся).
Подробнее о замыканиях: Закрытия не сложны