2

I have a script that needs a function to be run multiple times per object, but the number of objects is set in a variable by the user.

It would work like this

dothis(1);
dothis(2);
dothis(3);

However this doesn't work

for (var i = 0; i < howMany; i++)
{
    setInterval(
        function()
        {
            dothis(i);
        },
        (Math.floor(Math.random() * 10) + 1)
    );
}
cantsay
  • 1,967
  • 3
  • 21
  • 34

1 Answers1

2

You need to snapshot the value of i in a local scope otherwise it gets dynamically 'regenerated' at execution time, which means the value would then always be howMany, since the CPU lock, created by the main function, prevents your setInterval/setTimeout functions to execute before the loop is ended.

for (var i = 0; i < howMany; i++)
{
    setInterval(
        function(j)
        {
            return function() { dothis(j); };
        }(i),
        (Math.floor(Math.random() * 10) + 1)
    );
}

See How do JavaScript closures work? for further reference.

Community
  • 1
  • 1
Sebas
  • 21,192
  • 9
  • 55
  • 109
  • thanks. so I guess that would be the same as declaring another function that takes a value and then calls `dothis()` with said value, and then calling `newfunction(i)` which would in turn call `dothis()` with the value of `i`? – cantsay Nov 25 '14 at 17:59
  • 1
    No, because the scope of `i` would still be 1 level above `newfunction` (thus still being dynamically evaluated). The point of using the `j` parameter in my example is to make it *local* hence completely static. – Sebas Nov 25 '14 at 19:02