I'm trying to have a counter increase gradually. The following works:
function _award(points){
var step = 1;
while(points){
var diff = Math.ceil(points / 10);
setTimeout( "_change_score_by("+diff+");" /* sigh */,
step * 25);
points -= diff;
step++;
}
}
However, it uses an implicit eval. Evil! Let's use a closure instead, right?
function _award(points){
var step = 1;
while(points){
var diff = Math.ceil(points / 10);
setTimeout( function(){ _change_score_by(diff); },
step * 25);
points -= diff;
step++;
}
}
Obviously, this doesn't work. All closures created catch the last value diff
has had in the function -- 1. Hence, all anonymous functions will increase the counter by 1 and, for example, _award(100)
will increase the score by 28 instead.
How can I do this properly?
This is a known problem. But you can easily create a closure on each loop iteration:
Solving the Closure Loop Problem gets less messy with ECMAScript Fifth Edition's
Function#bind
method:You can hack this feature into browsers that don't support it yet to get the benefit now.
Nikita's approach works (thanks!), but personally I prefer changing it to this more explicit way: