
A summary of ECMAScript 6 features - sevko
https://github.com/lukehoban/es6features
======
spion
Despite what people may say, ES6 is turning out to be a pretty great language
all around. Type coercion is still pretty annoying and is there to stay, but
the new features are all mostly well done.

Now if we can only get the bind operator [1] in a timely manner, everything
will be awesome.

[1]:
[http://wiki.ecmascript.org/doku.php?id=strawman:bind_operato...](http://wiki.ecmascript.org/doku.php?id=strawman:bind_operator)

~~~
kevincennis
Hadn't seen that proposal before. It's definitely interesting.

My first impression is that it's kind of confusing to read, but I suspect I'd
get used to it.

Sort of similar to some of the destructuring assignment stuff, e.g. `let {
address: { street } } = user;`. Awkward at first, but now I'm kind of into it
– although I still think people are likely to abuse it.

------
wildpeaks
Also keep in mind that _Traceur_ adds its own global runtime, I usually
recommend _6to5_ instead (despite what the name suggests, it supports some ES7
features as well and even JSX).

Here's a good features comparison table of common transpilers:
[http://6to5.org/docs/compare/#comparison-to-other-
transpiler...](http://6to5.org/docs/compare/#comparison-to-other-transpilers)

------
rzimmerman
A lot of these features look great, and some of them are even useful. I think
it's a shame that async/await has to wait for ES7. It would really give some
direction to the node community and give JS an edge for async programming.
Generators just look like another awkward attempt to avoid callbacks by
jumping through different hoops.

~~~
aaron-lebo
Generators have long been used in the Python community for reasons other than
callback avoidance (they are lazy sequences). Generators in ES6 (as well as
several other features) seem to be inspired by Python.

There's no reason we'll have to wait for ES7. Seeing as how good 6 to 5
transpilers already are, I'm sure you'll be able to use await relatively soon.

~~~
rzimmerman
Generators in Python are a very useful feature (lazy sequences, like you
said), so maybe I spoke to soon. However, I don't think people should be
lauding this feature as some kind of solution to callback hell.

I just feel like priority-wise, users would benefit most from modules (which
made it), async/await, maybe class syntactic sugar, then everything else.

~~~
masklinn
> I don't think people should be lauding this feature as some kind of solution
> to callback hell.

Then async/await is no solution for it either.

~~~
rzimmerman
I think:

    
    
        app.get('/thing', function (req, res) {
          try {
            await user = db.get({user: req.user});
            res.send({user:user});
          } catch {
            res.send(400);
          }
        });
    

beats the hell out of:

    
    
        app.get('/thing', function (req, res) {
          db.get({user: req.user}, function (err, user) {
            if (err) return res.send(400);
            res.send({user:user});
          });
        });
    

especially when you have conditionals or loops that can look like:

    
    
        if (user.name == 'abc') {
          resp = 5;
        } else {
          await resp = db.get_resp({user:user});
        }
        await db.save(something);
    

I suppose it doesn't get rid of callbacks, just makes them readable.

~~~
masklinn
> I suppose it doesn't get rid of callbacks, just makes them readable.

 _You_ are the one who stated generators were no solution to callback hell but
async/await was, yet here's what your code looks like with generators:

    
    
        app.get('/thing', function* (req, res) {
            try {
                let user = yield* db.get({user: req.user});
                res.send({user: user});
            } catch {
                res.send(400);
            }
        });
    

...

------
wildpeaks
The ES6 transpiler "6to5" was renamed to "Babel" a few hours ago:

[https://news.ycombinator.com/item?id=9052478](https://news.ycombinator.com/item?id=9052478)

[https://twitter.com/markdalgleish/status/566909414242660353](https://twitter.com/markdalgleish/status/566909414242660353)

------
jarcane

        const map = (fn, [x, ...xs]) => (x === undefined) ? [] : [fn(x), ...map(fn, xs)];
    

This gives me the warm and fuzzies.

------
shittyanalogy
ECMAScript 6 is a mess

Now there's a completely new function syntax that doesn't use parens and has
different scope rules

    
    
        var odds = evens.map(v => v + 1);
    

Enhanced object literals:

    
    
        // Computed (dynamic) property names
        [ 'prop_' + (() => 42)() ]: 42

what?? So it uses parens if there are no params, but not otherwise?

Template Strings:

    
    
        `In JavaScript this is
         not legal.`

Seriously another String delimiter?

    
    
        `Hello ${name}, how are you ${time}?`

Why aren't we just using #{} like everyone else?

    
    
        // Construct an HTTP request prefix is used to interpret the replacements and construction
    
        GET`http://foo.org/bar?a=${a}&b=${b}...

What??

Destructuring:

    
    
        var [a, , b] = [1,2,3];

Is that seriously just whitespace and another comma?

Splats (spreads?)

    
    
        f(...[1,2,3]) == 6

... means destructure?

This is not readable code:

    
    
        let fibonacci = {
          [Symbol.iterator]() {
            let pre = 0, cur = 1;
            return {
              next() {
                [pre, cur] = [cur, pre + cur];
                return { done: false, value: cur }
              }
            }
          }
        }
        
        for (var n of fibonacci) {
          // truncate the sequence at 1000
          if (n > 1000)
            break;
          print(n);
        }
    
    

Symbols without a literal syntax: [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) Jesus Christ.

Unicode:

    
    
        "𠮷".length == 2

Awesome, still wrong.

Modules are cool. Promises are cool. Tail call optimization is cool.

This is not readable code:

    
    
        // Proxying a normal object
        var target = {};
        var handler = {
          get: function (receiver, name) {
            return `Hello, ${name}!`;
          }
        };
        
        var p = new Proxy(target, handler);
        p.world === 'Hello, world!';
    

ES6 is a mess. Javascript just got harder.

~~~
mythz

         var odds = evens.map(v => v + 1);
    

Is about as readable as it gets (inspired by C#, Java8, CoffeeScript), as a
benefit of succinct syntax sugar we get intuitive `this` binding - i.e. pit of
success.

    
    
        [ 'prop_' + (() => 42)() ]: 42
    

> what?? So it uses parens if there are no params, but not otherwise?

Again not surprising, a leading `=>` would be a syntax error so `()` is an
obvious compromise which can be naturally be extended to add args, e.g:

    
    
        evens.map((v) => v + 1)
    
    

> Seriously another String delimiter?
    
    
        `Hello ${name}, how are you ${time}?`
    

Yep, String interpolation is incredibly useful especially in JavaScript which
does a lot of string munging - this will lead to more succinct, readable code.
Should be obvious why they didn't want to break existing JS by re-using ""
double-quotes.

> Why aren't we just using #{} like everyone else?

Who's everyone else (Ruby inspired langs)? Scala uses ${1 + 1} or $var
shorthand (same as Groovy, Kotlin, JSP EL, Haxe), C# 6 uses {var}, Swift uses
\\(var) whilst Python and Java have string formats that use %(var)

    
    
        var [a, , b] = [1,2,3];
    

> Is that seriously just whitespace and another comma?

It's clearly ignoring matching the second element. Some languages choose to
use `_` as a special ignore placeholder, JavaScript chose not to. Either way
is not unintuitive with what it does so that's ok.

The other features are extremely useful if you need them, otherwise you can
happily ignore them and use the subset you're comfortable with.

------
jfaucett
Maybe its just me but the only things that I really like from this document
are "Unicode", and "Tail Call", though some other things may be nice, the
verbosity is killing me, how many new keywords, synatic constructs, and
symbols are coming in with ECMA6? Though I have no say in the matter, for my 2
cents, I just wish they had used ECMA6 to remove things (mainly those listed
here:
[http://johnkpaul.github.io/presentations/empirejs/javascript...](http://johnkpaul.github.io/presentations/empirejs/javascript-
bad-parts/) and in Crockfords famous book
[http://archive.oreilly.com/pub/a/javascript/excerpts/javascr...](http://archive.oreilly.com/pub/a/javascript/excerpts/javascript-
good-parts/bad-parts.html)) for instance.

~~~
esailija
In JavaScript you can't make any backward incompatible changes, let alone
remove anything. Because what browser would want to implement stuff that
breaks websites for its users?

------
transfire
It seems a little odd that class functions do not need a keyword. Speaking of
which it would have been nice if we could use the shorter `func` instead of
`function`. But in any case, I'm just glad private class members didn't make
the cut. Whomever was responsible for that, thank you!

------
qzcx
While a lot of these changes are cool, I'm worried that starting to work with
javascript just got a lot harder. Although, I do appreciate the Class foo
extends bar {...} syntax, now maybe we can have one simple way of doing
inheritance which is readable to someone new to javascript.

~~~
mmebane
A lot of it just feels like cleaner versions of patterns people have been
using for a long time. There's a few things I'm worried about:

* Tagged template strings might have some potential to be abused in interesting ways, since it looks like the tag function doesn't actually have to return a string.

* The Object destructuring/enhanced literals (and the Object rest/spread proposal in ES7) still take a _lot_ of mental energy for me to parse. I'm worried they could be a maintenance liability in large projects, but that remains to be seen.

* Async functions/generators in ES7 will probably take a while to get used to, as well, but I felt the same way about Promises when they were first introduced, and they didn't turn out to be too bad. I don't have an issue with normal Promises/generators, so this might just be a matter of me needing to see the async stuff as a whole instead of the sum of its parts.

~~~
cwmma
> A lot of it just feels like cleaner versions of patterns people have been
> using for a long time.

This was a pretty explicit goal, what they called 'paving the cow path'

------
z3t4
This is some scary shit!

JavaScript is a mainstream language. That means average people like myself can
be very productive with it. It is easy to learn and it's easy to find people
who can maintain JS code.

But it seems you need to be an academic in programming languages just to
figure out what these new features do, and why they are needed. I'm afraid
that the rapid development will make it harder to learn the language. And will
introduce a lot of pitfalls and edge cases.

Or maybe I'm just afraid of change!?

~~~
netcraft
this is an interesting perspective that I don't really understand and hope you
will expand on. Which parts of the es6 changes do you feel you need to be an
academic to understand? The es5 spec is 6 years old at this point and it feels
to me like es6 is taking forever to be implemented. Most of the changes are
there to make things more consistent and reduce pitfalls and edge cases - let
and const to solve the problems with var, fat arrows make functions cleaner
and solve the this binding problem, classes and modules formalize what
everyone has been trying to do in JS for years just in different ways. No
doubt there's some learning to do, but on the whole it seems like a very
conservative and solid list of enhancements.

~~~
z3t4
The majority of JS developers do not know what a scope is, what Destructuring
and Rest + Spread means, what a generator does, and have never heard of Map +
Set + WeakMap + WeakSet.

------
antjanus
Awesome list. I'm happy to have saved it. I'd love to see a post about how to
easily and quickly start transitioning without a hassle. :)

~~~
kevincennis
6to5 has been mostly pain-free for me.

Getting it to play nicely with my code coverage tool was a bit tricky, but
aside from that it wasn't bad at all.

Bear in mind that ES6 is fully backwards-compatible with ES5, so you can set
up a transpiler without having to actually rewrite your whole codebase right
off the bat. It's pretty easy to upgrade gradually if you need or want to.

------
skwosh
I would have liked to have seen:

* Skinny arrows as a shorthand for functions (for methods and constructors that don't get 'this' from outside.

* Rest parameters with trailing arguments, e.g.:
    
    
        function zip (...xs, f) { ... }
    

Seems like an oversight but I'm sure there was a reason (anyone care to
comment?)...

I guess arguments parsing isn't quite dead...

------
aikah
Unfortunately Symbols are not that useful when it comes to private properties
in classes. A better approach would be to use use weakmaps to have private
properties.

The problem with symbols is the absence of symbol literal syntax(along with
the fact that one can access symbols through reflection).

------
odiroot
It's really hard to find browser support information for each of those. And
every browser vendor chooses to develop every feature in different pace and
order.

~~~
oblio
[http://kangax.github.io/compat-table/es6/](http://kangax.github.io/compat-
table/es6/)

~~~
odiroot
I know about that. But seemingly it only shows limited set of browser
versions.

For me the most important thing is: what was the first version to support this
feature. So I know I can actually use it -- comparing to my users' browser
usage stats.

------
tomelders
What's the story behind `let` becoming the new `var`? Seems odd to me to
change the short hand for "variable" to `let`.

~~~
ealexhudson
`var` is still there, but it is scoped differently - `let` scopes to blocks,
e.g. if (foo) { let baz = 'quux'; ... }

`let` in function scope is the same as `var`, in block scope it's narrow, it's
basically the thing you want. `var` couldn't change, though, it would have
broken existing code - hence `let`/

------
g8gggu89
How long has it been now since the last version?

------
user_name2
* Slavery

