4 ms·
Except that Javascript has lexical scope. Use the var keyword to define local variables. foo = function(){ var bar=0 return function(){
by pygy_ 16y ago
Except that Javascript has lexical scope. Use the var keyword to define local variables.
foo = function(){
var bar=0
return function(){
bar=bar+1
return bar
}
}
baz=foo()
baz() // => 1
baz() // => 2
baz() // => 3
bar; // => ERROR: bar is not defined
- udp 16y agoThey'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() { })(); ). And nested loops that both use "i" would work.
- deleted 16y ago[deleted]
- sedachv 16y ago"I'd (personally) prefer it if it worked like C, and a variable was defined from the "var" statement until the next closing brace." It does work like C. The scoping you're talking about was introduced in C99.
- cyrus_ 16y agoSpidermonkey (or whatever they are calling it nowadays) supports this using the "let" keyword, fwiw.
- KeithMajhor 16y agoTry this: for ( var i = 1; i < 10; ++i ) setTimeout( function( ) { alert( i ) }, i * 250 ) You might expect it to alert 1..2..3..etc. It actually alerts 10..10..10..etc.
- udp 16y agoThat'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...
- KeithMajhor 16y agoI'm sorry my original post wasn't very clear. 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 )
- udp 16y agoThat 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.
- raganwald 16y ago> 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!
- Cushman 16y ago