Reputation: 12532
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?
Upvotes: 1
Views: 57
Reputation: 4906
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)
Upvotes: 2