
ES6: The features I'm most excited about - niix
http://justicen.com/#/posts/74046fea9a4c61477db9
======
ecaron
Wow. I can't believe template strings ([https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/template_strings)) aren't in this list. I'm
incredibly excited to start having those at my disposal.

~~~
zhodge
Hm, at first glance I am as well, especially with tagged template strings.
Those look particularly simple but powerful.

Generally though, is it reasonable for features such as these to be included
at the language level? I primarily use ES5 JavaScript so I'm used to pulling
in a decent amount of modules (in this case handlebars, underscore, etc.) for
things like templating.

But I will be relieved to have a language-standard solution to what feels like
such a common problem for the environments in which JS is used primarily,
despite the tradeoff that's made in accessibility due to feature bloat.

~~~
Pephers
I too was reluctant of using many of the new ES6 features, but as I've begun
to adapt them I've come to appreciate them a lot! In fact, when using Babel to
compile ES2015/2016 you can in many cases rid yourself of things like
Underscore/lodash[1], Promise libraries, etc.

I've recently started a new project in React/Flux, and I've cut away 3 or 4
dependencies compared to previous projects by fully embracing ES2015/2016, as
Babel automatically provides the necessary polyfills and compilation.

As for template strings, I think they make sense. Most programming languages
have them in someway or another, like Ruby "hello #{world}" or Python 'Hello
{world}'.format(world='World').

[1] [https://www.reindex.io/blog/you-might-not-need-
underscore/](https://www.reindex.io/blog/you-might-not-need-underscore/)

~~~
jdd
lodash has ~200 modular methods. That means it covers much more ground than
the handful of ES5/6 built-ins provided and because it's modular you can use
what you need without the stuff you don't.

------
spion
I don't understand why everyone considers classes controversial. If you look
at code in the wild, it already does what classes desugar to: everyone already
writes constructor function and attaches properties to their prototypes.

At least now with classes, users coming from other languages wont be as
tempted to make their own completely incompatible object systems.

~~~
dmak
While my example isn't an issue in ES6, most of the controversial came from
CoffeeScript. Using classes comes with classical inheritance expectations. In
CoffeeScript, changing class variables would carry through all instances, and
that is unexpected from a classical inheritance point of view. However, it
made complete sense in the compiled JS.

~~~
jestar_jokin
Maybe I'm misunderstanding, but isn't that the same as static properties on
classes in Java?

------
akst
My favourite feature is promises, while it doesn't add a new syntax and you
can probably add a library for it, the fact it's standardised makes a world of
difference. Now that it's standardised

1\. It will become the common interface for deferred operations and library
authors can make assumptions that it's there.

2\. ES7 Async/Await will be able to leverage this common interface.

~~~
mkozlows
My problem with promises is that delivering it without async/await is just
awkward. Because, yes, in the ES7 async/await world, you're going to want to
use promises heavily because they'll work so great with that.

But in the ES6 world, making your API promise-based makes it heavier-feeling
and more awkward than simple, clean callbacks. (Which get an unnecessarily bad
rap from people who don't work primarily in JS; there are cases when callbacks
get awkward, but just looking at code that's four levels of indent deep and
declaring it "callback hell" \-- as you so frequently see -- is a super-
shallow analysis. That code is clean and easy to understand, as often as not.)

~~~
tracker1
For the near term, you have to use something like babel anyway. Beyond that,
generators and promises need to be implemented ahead of async/await as they
are prerequisites for it.

------
pipeep
Even better: The arrow function example used the statement form of an arrow
function, instead of the expression form, which allows you to omit the return:

    
    
      // using arrow
      var adder = {
        num: 2,
        nums: [1,2,3,4,5],
        addIt() {
          return this.nums.map(n => this.num + n)
        }
      };
      
      console.log(adder.addIt()); // [3, 4, 5, 6, 7]
    

I'll concede that the arrow function is a bit overly complicated, with this,
sometimes-optional argument list parenthesis, and object literal/function body
syntax ambiguity.

------
AgentME
The first module example is incorrect:

    
    
        // myModule.js
        export function myModule(someArg) {
          return someArg;
        }
    
        // main.js
        import myModule from 'myModule';
    

The import is importing a non-existent default export. Either the export needs
to be changed to a default export:

    
    
        export default function myModule(someArg) {
    

-or- the import needs to be changed to importing a member:
    
    
        import {myModule} from 'myModule';

~~~
niix
Thanks, fixed.

------
nodesocket
I was just talking to my friend who works at NetFlix on the frontend team
about ES6, he is most excited about destructuring `let { name, age, gender } =
user;`. I however advocate that the new class syntax is the best part of ES6.
Take the following trivial OOP example, which I think reads so much easier a
lot like PHP.

    
    
        "use strict";
    
        class Vehicle {
            constructor(name) {
                this.kind = 'Vehicle';
                this.name = name;
            }
    
            printName() {
                console.log(this.name);
            }
        }
    
        class Car extends Vehicle {
            constructor(name) {
                super(name); //call the parent method with super
                this.kind = 'Car';
            }
        }
    
        let myCar = new Vehicle('Mercedes');
        console.log(myCar);

~~~
mkozlows
I think it's fair to say that people who want to write object-oriented
Javascript are very excited by class. Those of us who have found that the non-
OO nature of Javascript is part of what makes it so productive are... much
less excited.

~~~
jonpress
JavaScript is object oriented just like any other language. The difference is
that it is prototype-based OO instead of class-based OO.

I would say that JavaScript's OO is actually more powerful/flexible than other
languages but it is less readable and more error prone if you're not careful -
For example, the fact that objects can 'borrow' a method from other object an
apply it to themselves is a common source of issues for beginners.

~~~
smt88
It's possible to get power without flexibility. Flexibility is bad -- it
creates code that is idiomatic to the person who wrote it.

Rust and Go are so exciting because they've intentionally rejected flexibility
without compromising power.

~~~
tragic
Flexibility is not 'bad' \- it's a tradeoff. More flexible languages are
better for writing DSLs, etc; but using them means a lot of self discipline
regarding code style.

One thing I wish JS had is a PEP8-style canonical style document. I would find
that more useful than classes.

On classes, I am among the less excited about them; however, we are in a
ridiculous situation where there are about 500 different library
implementations of class inheritance. Backbone has one. Ember has one. Node
has util.inherits. Various transpile-to-JS languages (CS, TS) all have their
own slightly-different implementations of the resulting prototype code. There
is plainly a need for classes in JS, felt by some of the leading projects in
JS land.

ES6 classes at least gives all these disparate implementations a refactoring
target. How many of them will get there is another matter.

~~~
tel
> More flexible languages are better for writing DSLs, etc;

Citation needed, or, I'm not quite sure I agree with you there. In fact, I
think I believe the exact opposite (to a degree).

------
chjj
ES6 is a mixed bag for me.

I'm against block scope in a way. It's semi-useful, but it's just sugar. So
many features of ES6 seem to be designed for people who don't want to bother
learning javascript: classes, block scope, arrow syntax, etc. It's just trying
to shoehorn javascript into the template every other language follows when
javascript is _not_ every other language.

That being said, I like iterators, weak maps, typed arrays, TCO, and so on.

~~~
Kudos
Fat arrows are increasingly becoming one of my favourite additions.

No more `function() {}.bind(this);` since `() => {};` is equivalent. It makes
it clearer for the reader that the code block inherits scope.

------
charriu
I'm a bit worried about ES6 making the language harder to understand.

For example, scoping: For backwards compatibility reasons, var has to stay
function scoped. But now we also have let, which has different scoping rules.
Also, Symbols: [Symbol.iterator]() - what? Why?!

On the other hand, stuff like arrow functions, template strings, modules and
tail optimization are awesome.

~~~
alkonaut
Can someone explain the reasoning behind having any kind of backwards
compatibility? Who would pick a worse-but-compatible ES6 over a better
incompatible version?

For example, the scoping rules: why have two separate scoping rules for let
and var? To put it another way, would ES6 have let and var with differing
scoping rules if it was designed today? If not, then it's a flaw (any
difference from what a clean redesign would look like I consider a flaw).

Why not just make a simple and consistent syntax?

~~~
Touche
> Can someone explain the reasoning behind having any kind of backwards
> compatibility?

Not breaking millions of websites.

~~~
alkonaut
In what way would a cleaner ES6 break websites? Browsers aren't going to stop
supporting ES5.

~~~
bzbarsky
Browsers aren't likely to implement two separate languages either.
Furthermore, forcing people to pick between "ES5" and "ES6" if they just want
to use a single ES6 feature is pretty bad.

So your fundamental choices are really an ES6 that is backwards-compatible or
an ES6 that is not used.

~~~
alkonaut
On the other hand forcing newcomers to learn the warts of ES5 when they could
learn what is becoming a reasonably elegant language isn't ideal either. Two
scoping rules, for example.

An ES-latest runtime + transpilers would be all that browsers needed.

~~~
bzbarsky
This has in fact been debated back and forth on the es-discuss mailing list
and in TC39, especially given experiences with strict mode. The decision was
generally made to not have more modes and to just have a single JS language.

You don't have to agree with that decision obviously, but this isn't something
that happened willy-nilly.

------
tlrobinson
I agree with this list completely, but it doesn't mention one of the best
reasons generators and promises are awesome: async/await-style asynchronous
programming eliminates callback hell by letting you write asynchronous code as
if it were synchronous, including using control structures like conditionals,
loops, and try/catch.

And you can do it in (most) browsers today using a transpiler like Babel and a
library like Blurebird, Q, co, or task.js.

The rest of the things are nice, but promises/generators (and eventually
async/await) are game-changers.

~~~
amelius
The problem with Javascript generators, however, is that you're not allowed to
call other functions from them, which yield. This very much limits the kind of
async stuff you can do with them.

~~~
tlrobinson
Not really (at least not the kind of stuff I mentioned), those functions can
just return promises which the caller yields:
[http://codepen.io/anon/pen/WvzGLa](http://codepen.io/anon/pen/WvzGLa)

Granted async/await syntax will make this a bit nicer:

    
    
        async function funcA() {
          await sleep(1000);
          // ...

~~~
amelius
But then the called functions have to be written async style.

------
kriro
I think .bind(this) could be added as a (more common?) alternative example to
var self = this;

Personally I'm most excited about the module system. It's by far the most
confusing thing for our students (and hard to google since you end up going
down the rabbit hole of build systems etc.)

~~~
v413
With the introduction of arrow function you won't need to use .bind(this) as
arrow functions capture in their lexical scope the variables/keywords: this,
arguments, super.

e.g.

setTimeout(function(){alert(this.a)}.bind(this));

becomes simply

setTimeout(() => alert(this.a));

~~~
kriro
Yes, maybe my comment wasn't clear. I meant to say add ".bind(this)" as a case
that is replaced by => just like "var self = this;" or (...)(); for that
matter.

------
qudat
Coroutines are the game changer imo. I wrote a little presentation to
illustrate code flow: [http://afc.neurosnap.net](http://afc.neurosnap.net)

------
haberman
I've just been playing with Promises and like them a lot. But one thing I find
strange is that ".then()" creates a new promise, but with no way to reject it.

ie. I can't write:

    
    
      return new Promise((resolve, reject) => {
        // Do some stuff, call resolve()/reject() on success/failure.
      }).then((step1Val, resolve, reject) => {
        // Do some stuff, call resolve()/reject() on success/failure.
        // But this doesn't actually work, because the "then" callback
        // doesn't get resolve/reject as args.
      });
    

Instead I'm having to write this as the following, which is more verbose:

    
    
      return new Promise((resolve, reject) => {
        // Do some stuff, call resolve()/reject() on success/failure.
      }).then(new Promise((resolve, reject) = {
        // Do some stuff, call resolve()/reject() on success/failure.
        // But this way I don't get access to step1Val.
      }));
    

Another bummer of this style is that that the second step doesn't get access
to the first step's value.

~~~
15155
async/await solves error handling and hanging onto values quite nicely.

IMO you should use Babel and take advantage.

~~~
grandalf
link to example please

~~~
15155

      async function foo() {
        try {
          const valueOne = await promiseReturningFunction();
          const valueTwo = await anotherAsyncFunction(valueOne);
    
          return valueTwo;
        } catch (err) {
          alert(err);
        }
      }
    
      foo(); //Returns a Promise.

\----

In this example, I've sequenced the resolution of two promises (async
functions return Promises when invoked)

If either of these Promises reject or throw an error, or if any of the code
within the try {} block throws an error, the error will be caught inline in
the catch block (one area only).

You can also see that both Promise's return values are in-scope and
continually usable (vs. losing scope with 'then' chains).

~~~
grandalf
I see. Not sure what the best practice is for the losing scope in then chains
issue with promises. I ended up creating something along the lines of a
message object designed for each chain, which felt like a smell.

~~~
15155
Feels like an un-compiler-assisted State monad.

IMO threading an object through is probably the best method, unfortunately.
You could use an Immutable Record or something to help keep it under control.

I would personally just use async/await to more explicitly handle the
sequencing/binding.

~~~
grandalf
Agreed. I think I'll refactor... thanks for the example.

------
joeax
Although arrow functions are nice, they've been around in the form of lambda
expressions in C# and other languages for some time, so the initial reaction
was more of a "about time" rather than a "wow!" for me. Same goes for
generators/yield keyword.

Thanks for pointing out the key difference between arrow functions and inline
functions being the context of 'this'. 'this' is going to be a source of
confusion for a lot of people.

~~~
todd3834
Yes, a lot of the new features are very "about time" but that doesn't remove
the excitement to now have them as a part of JavaScript.

'this' without arrow functions is currently a huge source of confusion. I feel
like the arrow functions will help to alleviate a lot of that confusion.

~~~
joeax
My biggest excitement is that in the past few years JavaScript is now regarded
as a first class language, and we're seeing these new versions i.e ES 5,6,7 in
a rapid development cycle. I remember being told in the 2000-2002 era that JS
was a kiddle language and it was worthless on a resume.

------
pjmlp
Now just throw away the DOM, replace it with something more suitable for
applications instead of documents, and we can have something akin to Smalltalk
back.

------
dpweb
Promises I find rather ugly to read. So far Im liking arrow functions and
template strings. Async/await I'm looking forward to in ES7.

~~~
savanaly
What exactly did you have in mind other than "new Promise()" to create a
promise?

~~~
striking
new Promise(function(resolve, reject){ /* code */ })

it's a little much

~~~
tlarkworthy
Ideally, if you're writing business logic, you shouldn't be creating promises
but consuming/combining/chaining them from libraries.

~~~
taternuts
What would make you say that? Why wouldn't you use promises in your business
logic?

~~~
DCoder
The idea isn't "don't use promises", it's more "use/chain the promises you
already got from libraries (e.g. AJAX calls), don't construct new promises
yourself". See the StackOverflow question inglor linked to:
[https://stackoverflow.com/questions/23803743/what-is-the-
exp...](https://stackoverflow.com/questions/23803743/what-is-the-explicit-
promise-construction-antipattern-and-how-do-i-avoid-it)

------
pubby
I'm new to Javascript, and am wondering if I be writing ES6 instead of ES5. Is
that a good idea, or should I wait a few months/years?

~~~
niix
There is no harm in either. Overall, just have fun and learn JavaScript :)

ES5 is the current standard in all major browsers, so using its functionality
could be considered "safe". Thankfully we have transpilers (will convert your
ES6 code to ES5), so you can use ES6 features in production today - just
remember they are converted to an ES5 implementation of said functionality.

------
zoz
I was a little confused by the constructor for Player in the class example.
Wouldn't the following be more appropriate:

    
    
      constructor(x = 0, y = 0) {
        this.x = x;
        this.y = y;
      }
    

(i.e. this way if "new Archer('Legolas', 5, 6);" the x and y values will not
be ignored.)

~~~
niix
Sure that works too, plus its a great way to point out initializing default
arguments.

------
koolba
What's the point of promises being part of ES6?

I understand them and use them quite a bit. I just don't understand why
they're in the language spec. They don't add anything new to the language (
_vs say generators or symbols_ ).

Is it purely for performance?

~~~
AshleysBrain
It allows web APIs built-in to the browser to return a promise, e.g.
audioContext.decodeAudioData(data).then(...). If you just used a library, the
browser wouldn't know how to wrap the returned value in a promise. It also
guarantees interoperability between all APIs using promises, avoiding any
incompatibility between different libraries.

------
_pmf_
Catching up a bit with C#, I see.

------
scriptle
The example quoted under "Arrow functions" is NOT "arrow function". It's an
enhanced object literal.

~~~
echeese
There is one in the addIt function.

------
chengas123
When will browsers start to implement these features? I'm looking forward to
being able to use modules in Chrome.

~~~
etblg
The other features? Already being done: [https://kangax.github.io/compat-
table/es6/](https://kangax.github.io/compat-table/es6/)

Modules? That may be a while, and isn't a big concern since until HTTP2 is in
wide effect (which may be really soon anyways) it makes more sense to just
package the files in to one file (which you can do right now) using
Browersify, JSPM, Webpack, or what have you than having the client request a
whole bunch of javascript files at once.

------
m1sta_
I hope our IDEs get smart enough so that destructuring features result in
pseudo named function parameters.

~~~
z3t4
I'm working on a JavaScript editor. But doesn't understand. Can you be more
elaborate!?

------
github-cat
So will someday there be interface in JavaScript?

------
andyl
I've used ES6 and prefer coffeescript - IMHO more concise, easier to read, and
has been place for years.

~~~
jessaustin
Yup. It's as if coffeescript was created by one person (and a bunch of great
PRs!), while ES6 came out of a committee.

~~~
skuunk1
That's exactly what I like about ES6 (the fact that it has come out of a
committee and is now a standard).

~~~
jessaustin
Leaving aside the committee preference, what value do you perceive in the fact
that it's a standard? It can't be that browsers support it, because they
don't. Sure Mozilla will probably get there within the next several years, and
Chrome won't be too far behind, but forget about Safari and IE. So you'll
still have to use Babel or something like it. Please note, _there 's nothing
wrong with requiring a tool chain_, which we already need anyway for
minimization, compression, cdns, etc. But once we realize that, we realize
that coffeescript is just the same as ES6 in that respect.

~~~
andyl
Well said. Many who rejected coffeescript because it required a tool chain now
embrace ES6 which requires a toolchain. People rave about ES6 features like
classes, arrow functions, destructuring, variable interpolation - as if they
are something new. Maybe the best thing about ES6 is that it helped
transpiling to be accepted as a mainstream technique.

