Closures are important in JavaScript, but it is important to understand what exactly you are closing over. To rework your current code (kind of).
function(){
var i;
for(i=0;i<10;i++){
setTimeout(function(){
console.log(i);
}, 1000);
}
}
In this example, your code is basically closing over var i;, which means that when the timer runs, it will read the value of var i; and print that out. In this case, as you have seen, when the timer runs, the loop has finished and the value is 10.
What you want to do is create a new function scope that captures the value of i at a specific time.
function(){
var i;
for(i=0;i<10;i++){
(function(iInner){
setTimeout(function(){
console.log(iInner);
}, 1000);
})(i);
}
}
This example will create a new anonymous function, and then calling it immediately in the loop, and pass the current value of i into it, so that when your timer reads iInner, it will read the value that was passed into the function, rather than the value from var i;. You can also just call iInner i if you want, but I've used two different names for clarity.
There are also helpers that you can use, like .bind that will essentially automatically create a new anonymous function for you, and pass in arguments like this.
function(){
var i;
for(i=0;i<10;i++){
setTimeout(function(iInner){
console.log(iInner);
}.bind(null, i), 1000);
}
}
<func>.bind will take the value of i and return a new function that passes those args through to <func> when called, and you avoid having to create another layer of nesting.