They're "hoisted" and only local to the function, though. I'd (personally) prefer it if it worked like C, and a variable was defined from the "var" statement until the next closing brace. Then you could have a variable local to one branch of an if statement, etc, without faking scopes by abusing closures (eg (function() { })(); ).
That's because closures actually capture the variable, not the current value of it. They'd be a lot less useful if they just made a copy of the variables...
My intended point was that if Javascript had true lexical scope then each iteration of the loop would create a distinct variable. A reference to that variable would then be captured by each closure. You can simulate the behavior of lexical scoping by "abusing" closures as someone mentioned before. Like this:
for ( var i = 1; i < 10; ++i ) ( function( i )
{
setTimeout( function( )
{
alert( i )
}, i * 250 )
} )( i )
> You can simulate the behavior of lexical scoping by "abusing" closures as someone mentioned before.
I wonder about the word "abusing" here. Languages that have block-level lexical scoping (I hope I am using the correct word) sometimes implement block scoping by renaming the variables and hoisting them to the enclosing function, and they sometimes implement block scoping by creating a new closure just as we do by hand in JavaScript, and then hoisting the result.
For example, naïve implementations of Scheme give you a "let" macro that is expanded into the closure form you give above, and then an optimizing step comes along a little later and performs lambda hoisting for you. So this "abusing" we are doing is what the language would have done for us in certain implementations anyways!
That isn't lack of lexical scope. It's that the for() syntax isn't purely functional in how it binds variables. One could define an equivalent syntax in Scheme and see the same result.
That was me who mentioned it, actually :-) Yes, I see what you mean now, sorry!
This reminds me of bug in the Visual C++ 6.0 compiler, where a variable declared in the "head" of a for loop would continue to exist after the loop scope had closed. Javascript has exactly the same problem, but by design, due to only having global and function-level scope.
Personally, I would like to be able to choose the capture method, but having value capture the default. Most of my code simply wants the value, but occasionally, capturing the variable is needed.