2

Please let me know if I'm coming at this block on a wrong angle. I have a series of functions I'd like to fire off, and I'd like to be able to set them all up in a loop.

for(var jj = 0; jj<monster.frames.length;jj++){
    setTimeout(
        functionName(jj),
        1000*jj
    );
}

The problem is that when that when functionName(jj) is exectuted, it's being passed the value of jj which by that time has been changed to the last loop iteration value.

Draculater
  • 2,280
  • 1
  • 24
  • 29
  • 2
    possible duplicate of [Javascript closure inside loops - simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – davin May 17 '12 at 09:06
  • http://stackoverflow.com/questions/341723/event-handlers-inside-a-javascript-loop-need-a-closure http://stackoverflow.com/questions/1331769/access-outside-variable-in-loop-from-javascript-closure http://stackoverflow.com/questions/1413916/javascript-closure-immediate-evaluation – davin May 17 '12 at 09:07
  • duplicate-->http://stackoverflow.com/questions/2171602/settimeout-and-anonymous-function-problem – rt2800 May 17 '12 at 09:08

2 Answers2

13

You need to ensure the inner function has a new variable for every iteration. The easiest way to do this is to create a self-executing anonymous function which receives the variable as an argument. You also need to fix the way you are calling the function - right now you register the return value of functionName(jj) as a callback. This would only be ok if that function actually returned a function.

for(var jj = 0; jj<monster.frames.length;jj++){
    (function(jj) {
        setTimeout(
            function() { functionName(jj); },
            1000*jj
        );
    })(jj);
}

You can also use partial application to create a new function. However, old browsers do not support Function.prototype.bind so you'd have to add a shim for it.

for(var jj = 0; jj<monster.frames.length; jj++){
    setTimeout(functionName.bind(this, jj), 1000*jj);
}
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
1

Give this a go:

for(var jj = 0; jj < monster.frames.length; jj++)
{
    (function(x)
    {
        setTimeout(function()
        {
            functionName(x)
        }, 1000 * x);
    })(jj);
}
Richard
  • 8,110
  • 3
  • 36
  • 59