Having coded JavaScript professionally and enjoyed it thoroughly for 6+ years now, I respectfully degree. The Harmony project shows just how much work there is to be done to make JS more fun/practical to use day in and day out.
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.
My most common annoyance about Javascript is the lack of bound methods like in Python Ruby etc. When you specify callbacks, you always have to provide the value of 'this' as well. If you forget, it's basically random and you're in for some heavy debugging.
'this' is evil in Javascript. The very first line in any constructor function that I write is:
var that = this;
From then on, I use 'that' instead of 'this', relying on closure magic to make things work. You never have to worry about how the function is bound thereafter.
Thanks. I think I like that solution, as it's extremely simple. Are there any drawbacks?
CoffeeScript is cool, as it is basically "Python in JS" but I have some resistance against languages that convert to other languages. I'm not so sure why.
No, no drawbacks that I'm aware of. You're basically using a closure to bind the object to the callback, instead of using Javascript's weird 'this' binding rules, that's all...
That's mostly just true for browsers. Javascript itself has very few faults.
My biggest annoyances with the language are: Lack of lexical scope, no trailing commas and semicolon usage that differs from C.
I could complain all day about my annoyances with browsers (or just IE).