Clearly ES6 is a huge improvement over ES5, and tools like 6to5 allow us to use these cool features now. I was reading Replace CoffeeScript with ES6 by Blake Williams and thought it was a great summary of how ES6 solves many of the same problems that CoffeeScript solves; however I’d like to comment on a few of Blake’s points and talk about why I’ll be sticking with CoffeeScript.
Classes
Classes in ES6 (like many of the syntax changes in ES6) are very similar to the CoffeeScript equivalent. To support browsers that are not fully ES5 compliant (e.g. IE8-), however, we still can’t really use getters/setters, so ignoring these the comparison is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
vs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
I definitely like the way this is headed - no need for commas, no need to write function
all over the place; but I’m in the “write less code” camp, so I prefer the former. However this is really a matter of taste so if you’re happy with typing this.
instead of @
and adding in all the extra curly brackets it definitely backs up Blake’s statement that ES6 is a viable alternative.
That said, I much prefer CoffeeScript’s implementation of super
, though I can see why ES6 went the way they did allowing you to call a different method on the object’s super.
Interpolation
Clearly ES6’s and CoffeeScript’s string interpolations are very similar; CoffeeScript interpolates for normal "strings"
, whereas ES6 uses `backtick escaped strings`
(which are annoying to write in Markdown, by the way). CoffeeScript uses #{var}
whereas ES6 uses ${var}
. All much of a muchness at this point.
Where the difference really stands out is in the handling of whitespace - ES6 (or at least the 6to5 tool) includes all the whitespace between the `
s (including newlines and indentation), whereas CoffeeScript either joins with a single space in the case of simple "
strings or preserves all whitespace accounting for indentation level in the case of """
block strings. To my mind both of these behaviours are desirable, whereas ES6’s is not, take for example:
1 2 3 4 5 6 7 8 9 |
|
The output from passing this through 6to5’s REPL is:
1
|
|
CoffeeScript equivalents:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
produce
1 2 |
|
I can’t think of a situation where I’d prefer 6to5’s implementation.
Fat Arrows, Default Arguments
Brilliant additions to the JS syntax, these behave the same as CoffeeScript’s but with ever-so-slightly different syntax rules.
Splats
Another brilliant addition, but I find splats can be quite powerful in the middle of an argument list, particularly in Node.js-style callback situations so that the callback is automatically popped off the end. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Sadly ES6 only allows splats at the end, requiring you to then manually pop()
the callback (or lastName), making your code longer and making you choose more variables names (and we all hate picking variable names right?):
1 2 3 4 5 |
|
Structuring/Destructuring
I must say I do like that ES6 lets you leave true blanks when doing var [first, , last] = [1, 2, 3]
but using an underscore or similar is a one character workaround.
ES6 does object de/structuring pretty much the same as CoffeeScript (var {a, b} = {a: 1, c:3}
, var {foo: a, bar: b} = {foo: 1, baz: 3}
and var c = {a, b}
) however there’s a slight circumstance where CoffeeScript does it better: when referencing properties off of the current object, e.g. c = {@a, @b}
(var c = {a: this.a, b: this.b}
).
Things ES6 has that I wish CoffeeScript had
It wouldn’t be fair to try and paint CoffeeScript as a perfect language - it certainly is not without its faults. Here’s a list of features from ES6 (and even ES3) that I miss in CoffeeScript:
- The ternary operator
a ? b : c
(if a then b else c
is too verbose for my taste; that said there’s no way I’d give up the?
operator!) - Computed (dynamic) property names,
{[getKey()]: getValue()}
(see the links in this StackOverflow answer for some interesting history)
Conclusion
All in all ES6 is a great leap forward for JavaScript and my huge thanks to all the developers who have made this possible. Not mentioned above are many of the features that ES6 has added that don’t involve syntax changes and hence CoffeeScript can use without changes, such as Proxies, WeakMaps and much more. (We even have yield
now too.)
I still prefer CoffeeScript’s syntax and find it very readable yet concise which significantly boosts my productivity. I would also find it hard to give up all CoffeeScript’s various syntax sugars, such as: object?.property
which doesn’t throw if object is null/undefined; a ?= b
, a ||= b
, etc.; implicit returns; unless
; improved switch
; ranges [a..b]
; array/string slicing with ranges arr[2..6]
; for own k, v of obj
; chained comparisons a < b < c
; block RegExps; and many more!