1

It isn't really a problem for me. I just want to know how I can do it correctly, and not with a workaround. Well, if we use for() and some delayed events, only the last value is considered.

Test: http://jsfiddle.net/39dQV/

// Using only i (does not work)
for(var i=0; i<10; i++) {
    setTimeout(function() {
        test1.textContent = i;
    }, i * 1000);
}

// Private scope to i (does not work either)
for(var i=0; i<10; i++) {
    var x = i;

    setTimeout(function() {
        test2.textContent = x;
    }, i * 1000);
}

// Callback scope (workaround)
function set_textContent(i) {
    setTimeout(function() {
        test3.textContent = i;
    }, i * 1000);
};

for(var i=0; i<10; i++) {
    set_textContent(i);
}​

What do I need do that to so it works correctly, ie: consider the current value of i, instead of the last value changed by time?

3
  • JavaScript only establishes scope at the function level. Thus, your function approach is correct, though there are variations on the same idea. Commented Oct 26, 2012 at 21:04
  • 1
    You want let, but it's basically nowhere supported. Commented Oct 26, 2012 at 21:05
  • Possible duplicate of [settimeout-in-a-for-loop-and-pass-i-as-value][1] [1]: stackoverflow.com/questions/5226285/… Commented Oct 26, 2012 at 21:06

1 Answer 1

2

Your solution isn't really a "workaround", it's nearby the best way:

for(var i=0; i<10; i++) {
    setTimeout(function() {
        test1.textContent = i;
    }, i * 1000);
}

Can't work! i is in local scope an not longer defined when the function is executed.

for(var i=0; i<10; i++) {
    var x = i;

    setTimeout(function() {
        test2.textContent = x;
    }, i * 1000);
}

Same situation here, x is local in the loop.

You need a own scope for your variable. The only way to define such a scope, is to encapsulate the definition of your timeout function inside a closure or function, like you did in your third way.

I'd write it so:

for(var i=0; i<10; i++) {
    ( function( i ) {
        setTimeout(function() {
            test1.textContent = i;
        }, i * 1000);
    } ( i ) };
}

the closure defines its own scope, so the value of i is stored.

For more deeper information see: http://www.javascriptenlightenment.com/ (I love it)

Sign up to request clarification or add additional context in comments.

1 Comment

I think my way is faster jsperf.com/private-scoping-speed-test. 10x more. :) But thanks.

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.