1

What is the main difference between:

    var test=[5,6,7,8,9];
    $.each(test, function (i, num) {
        setTimeout(function(){console.log('i: '+i+'  '+num)},500);
    });
    for (var j = 0; j < test.length; j++) {
        setTimeout(function(){console.log('j: '+j+'  '+test[j])},500);
    }

First loop outputs:

i: 0  5
i: 1  6
i: 2  7
i: 3  8
i: 4  9

Second loop outputs:

5 times 'j: 5 undefined'

I understand why the second loop does this, but not why $.each works 'as expected'

Thanks!

4
  • 1
    If you know why the second loop does that, then you should know how it differs from the first one. So, what's the difference? What's the issue in the second loop? Commented Oct 28, 2015 at 15:33
  • The second example does not work because there is a closure. The first example fixes that by creating a function for every iteration (thus creating a new scope) Commented Oct 28, 2015 at 15:36
  • @ValentinS.: To prevent any misunderstanding: There is still a closure in the first example. Commented Oct 28, 2015 at 15:38
  • Yes. I apologize. Indeed, the first example does not fix in the way that it does not create a closure, but it fixes in the way that it avoids the effect of the closure. Commented Oct 28, 2015 at 15:40

1 Answer 1

1

In the first snippet's behind the scene, for every iteration the call back that you have supplied will be called. That means, internally it will create a scope per iteration. That eventually becomes a cloure.

But in the second snippet. The initial scope will be used while the timeout's call back got triggered. So it is displaying that output. And you can make it work by using the following code,

for (var j = 0;j<test.length-1;j++) {
 var scope = function(i) { 
  setTimeout(function(){console.log('j: '+i+'  '+test[i])},500);
 };
 scope(j);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that solved it, i actually had ajax call in the for loop, so i used self-executing anonymous function for (var j = 0; j < test.length; j++) { (function(j){ setTimeout(function(){console.log('j: '+j+' '+test[j])},500); }(j)); }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.