var elem, formValues;
formValues = (function() {
var _i, _len, _ref, _results;
_ref = $('.input');
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
elem = _ref[_i];
_results.push(elem.value);
}
return _results;
})();
That's... needlessly bad, so to speak. That could be rewritten in a much more readable fashion, like so: var formValues = (function(inputEls) {
var results = [];
inputEls.each(function() {
results.push($(this).val());
});
return results;
})($('.input'));
If CoffeeScript is generating the first block seen here, then I'd actually be concerned, but perhaps I care more about this than some. Either way, while... formValues = (elem.value for elem in $('.input'))
...is certainly nicer, I don't really think it's necessary to further bastardize the views held on Javascript syntax in general. The first block in this comment is, to put it bluntly, utter shit, and does nothing but continue the trend that "oh god Javascript is horrible". $(this)
would resolve to `$(window)` in your function. To avoid that, you'd need to use `.call(this)`... but then how would you compile `break`, `continue`, etc.?I'm not saying CoffeeScript's output has no room for improvement, but given the challenge of compiling to working JS in all cases without modifying prototypes or adding tons of helper methods, I think you're being a little harsh.
The entire article was about jQuery and CoffeeScript, so my example was built using jQuery. This entails a .each method on DOM collections, and $(this) will properly scope being inside that $().each method.
M1573RMU74710N summed up what I aimed to do here, though, which was show that the resulting code isn't actually that bad. In my opinion the article in question is making a case that all Javascript looks horrible, when in reality that's simply not the case.
Edit: I see it noted in another comment on this thread that you're writing a book on this... and you couldn't tell I was using jQuery, when I pass in the results of the selector call as an argument? Tut tut...
Note in both Klonoar's example and the article, we are using jQuery.
In Klonoar's example inputEls is a jQuery object with a collection of input elements, which does have an each method.
When you use a method like .each() jQuery will also apply the function to each element in the collection in turn, so on each execution the context of the function is the element, so Klonoars example is correct.
That said, I think it's obvious that a compiler will not produce code as pretty as what a human would write, and that's generally ok. For the most part you only look at the compiled code for debugging, and as long as the generated code is fairly readable it shouldn't hinder that much.
Though more verbose and a little more ugly, the compiled Coffeescript JS has some benefits over Klonoars example.
In the CS version the crux of the iteration is a for loop which will be pretty fast. In the Vanilla JS version it's using jQuery .each() which will most likely be slower.
It is a good point to bring up though because there is some overlap in the goals and functionality of something like Coffeescript vs many libraries like jQuery. The difference is with Coffeescript you are paying upfront with compilation and with jQuery et al you are paying at runtime.
The cost-benefit analysis is something each developer must run for themselves and continually re-evaluate as they work.
$.post(
"/posts/update_title"
new_title: input.val()
id: something
-> alert('done')
'json'
)All coffeescript really did there was remove the commas and subtly change the syntax. That's not an improvement at all, it's just a lateral syntax change. If anything, the lack of commas almost makes it harder to read.
Why change to coffeescript and add another step (compilation of coffeescripts) into the mix when jquery was already pretty good to start with? Just seems like its something that would make it hard to take on new coders when your business starts scaling because they would need to know yet another meta-abstraction.
I'd call the gains "small but significant" in that case. The corresponding JS would be
$.post("/posts/update_title", {
new_title: input.val(),
id: something
}, function() {
return alert('done');
}, 'json');
What I really dislike about this is the use of curly braces to denote two completely different things: an object literal, and a function. Functions are extraordinarily privileged entities in JavaScript; they're the only way of creating scope, and they also change the context (`this`). Object are just a bunch of key-value pairs.So to me, JavaScript's semantics are much clearer through the lens of CoffeeScript semantics: Curly braces are only used for object literals, and functions are denoted by a distinct symbol followed by indentation, except in one-liners like the above.
The extra compilation can be annoying (through largely transparent thanks to tools like Barista and the upcoming Rails 3.1 integration), but for me, it's always felt worth it. Debugging is harder, true, but I write code with fewer bugs in the first place. On net, learning CoffeeScript has been both a pleasure and a productivity boost.