
ES6 Cheatsheet - DrkSephy
https://github.com/DrkSephy/es6-cheatsheet
======
krisdol
Wow, var was so broken.

Anyway, we use as much ES6 as Node 4 allows at work. Transpiling on the server
never made much sense to me. I also used to sprinkle the fat-arrow syntax
everywhere just because it looked nicer than anonymous functions, until I
realized it prevented V8 from doing optimization, so I went back to function
until that's sorted out (I don't like writing code that refers to `this` and
never require binding, so while the syntax of => is concise, it is rarely used
as a Function.bind replacement). Pretty much went through the same experience
with template strings. Generator functions are great.

I'm not a fan of the class keyword either, but to each their own. I think it
obscures understanding of modules and prototypes just so that ex-Class-based
OOP programmers can feel comfortable in JS, and I fear the quagmire of
excessive inheritance and class extension that will follow with their code.

~~~
Rezo
Transpiling on the fly on the server is even more painless than for the
frontend:

\- Require babel-core/register (as of Babel 6) \- Require your server entry
point ES6 file. \- Done.

Everything just seems to work, no need for sourcemaps or anything; line
numbers, error reporting, non-ES6 modules, everything Just Works. Haven't had
a single issue since starting to do this 4 months ago (knock on wood). Highly
recommended!

~~~
mercer
The babel documentation says it's a bad idea to do this in production, so I'm
thinking of using webpack to transpile then entire back-end to one ES5 file.
Do you know enough about this situation to tell me if this is a bad idea or
not? Because obviously your approach would be 'simpler'.

Edit: An additional reason to transpile to ES5 is that on the whole much of
the ES6 support is not very performant yet. While this might not matter for
incidental uses of, say, template strings, it might become noticeable for an
entire project. Or is that a clear case of premature optimization?

~~~
mstade
There's no difference in compiling to ES5 versus hooking into the module
loading mechanism to compile on the fly, in terms of the end-result. The only
practical difference is that precompiling means your modules will _load_
faster the _first_ time, but there will be no difference for subsequent loads
since modules are cached. I'm guessing the caveat for running something like
babel-register in production is the first-load performance penalty, as well as
having less control over the compilation process. However, if you are ok with
configuring babel through .babelrc files alone, and you're ok with the first-
load performance penalty, I don't see what it'd be any worse than precompiling
to ES5. (There may be subtle differences in debugging due to the lack of
source maps, but I don't know enough to comment on that with any degree of
certainty.)

~~~
mercer
That's informative, thanks. At least I have something to look into, and a
quick search indicates that source maps are not even necessary in this
approach!

------
pcwalton
> Unlike var, let and const statements are not hoisted to the top of their
> enclosing scope.

No, let _is_ hoisted to the top of the enclosing scope [1] ("temporal dead
zone" notwithstanding). let, however, is not hoisted to the top of the
enclosing _function_.

[1]: [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Statements/let)

~~~
mercer
I'd say that makes you technically correct, but practically speaking, if using
let before it's declared (assigned?), this temporal dead zone, results in an
error, it's pretty much not hoisted in the way that most of us think of it.

Or is there a use case that I'm not aware of where the hoisting is beneficial
despite the temporal dead zone?

~~~
pcwalton

        let f = function() { ... g(); ... }
        let g = function() { ... f(); ... }
        f();
    

Works despite the temporal dead zone and depends on hoisting. This exact
example is why hoisting was kept for let.

~~~
mercer
Interesting. This kind of stuff makes me want to dive into the details of
these kinds of choices, as I regularly wonder why languages designed are a
certain way.

------
Raphmedia
I would recommend taking a look at this page for a bigger "cheatsheet":
[https://github.com/lukehoban/es6features#readme](https://github.com/lukehoban/es6features#readme)

------
abustamam
I love how concise this is an handles a lot of "Gotchas" when working with
ES6, but can we call a spade a spade and NOT call this a "cheatsheet?"

I always imagine cheatsheets to be just that; something I can render on one
sheet of paper. Printing the entire raw README text would take 4 pages (2
sheets, front and back).

I think it would be better titled, "ES6 best practices" since I think that's a
more accurate description of what it is.

------
jcoffland
Great reference and overview of ES6.

One minor quibble. I was bothered by the misuse of the words "lexical" and
"interpolate". The lexical value of the keyword "this " is the string "this".
Then, you might translate between two technologies such as CommonJS and ES6
but interpolating between them implies filling in missing data by averaging
known values. Granted this word is commonly abused. Sorry this is a bit
pedantic but these corrections would improve the document, IMO.

~~~
wesleytodd
> By sticking to this paradigm, we make our code easily readable and allow
> ourselves to interpolate between CommonJS and ES6 modules.

This sentence should probably say "interoperate"

~~~
jcoffland
I believe you are right.

------
igravious
The only thing from this list of new ES6 idioms that doesn't sit comfortably
with me is the short-hand for creating classes. I remember being kind of blown
away way back in the day with the prototypical/functional nature of Javascript
and how you could wrangle something into being that behaved in an object-
oriented manner just like other languages that had explicit class declaration
and object instantiation.

Part of me feels that obscuring Javascript's roots in this respect is very un-
Javascript-y. What think ye?

Coming from Ruby, loving template literals, feel right at home with them, I
wish even C could have them (if that makes any sense!).

~~~
khalilravanna
I think the cheatsheet does a great job of summarizing what makes me
uncomfortable with es6 classes:

>"...the syntax for creating classes in ES6 obscures how implementation and
prototypes work under the hood..."

Yes, it's great for if you're uncomfortable with prototypal inheritance and
the "javascript way of doing things" (I'll maybe summarize that as composition
over inheritance, mixins, knowing how to use call/apply etc.), but at the end
of the day I'm worried it might be a crutch. Specifically, it might create the
situation where a javascript noob might use es6 classes and never bother to
learn how the prototypal chain works or all the myriad options available for
mocking classes and OO behavior. That being said, maybe that's a shitty
argument. When you have more tools in the toolbox there's always the option
for someone picking the wrong tool. Does that mean you take the tool out? Or
leave it because it is really useful when you know when to use it correctly. I
imagine the latter.

~~~
igravious
Agreed. And I meant prototypal, not prototypical :)

------
deckar01
Is "WeakMap" really the suggested way to implement private class properties?

Using "this" as a key into a Map of private variables looks bizarre. I would
rather keep my code concise than create a layer of obfuscation.

~~~
pcwalton
It was really hard to make truly private properties that couldn't be leaked in
some way without WeakMap. If you don't need foolproof leakage, Symbols are a
more convenient way to get most of the benefits of private properties. This is
intentional: as I recall, the committee realized that WeakMap wasn't the most
ergonomic solution and created Symbols as a more convenient, though less
ironclad, alternative.

~~~
mstade
Additionally, symbols would have provided a neat way to implement private (and
privately shared) properties, if they hadn't decided on adding the
`getOwnPropertySymbols` function[1]. Bummer.

[1]: [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols)

~~~
pcwalton
There were other ways to leak symbols before that method was added. They were
never foolproof.

~~~
mstade
Oh? Would love to be enlightened!

------
banku_brougham
Much more than a cheat sheet, this is a revealing window into js development.
Helpful!

------
TheAceOfHearts
This cheatsheet is wrong about ES2015 modules. They don't define how module
loading works, that's still being worked on [0]. ES2015 just defined the
syntax.

[0] [https://github.com/whatwg/loader](https://github.com/whatwg/loader)

------
edem
[This]([https://ponyfoo.com/articles/es6](https://ponyfoo.com/articles/es6))
is also a very informative guide of ES6. I highly recommend perusing it.

------
shogun21
Two questions: what happens if you use ES6 standards in a browser that does
not support it?

And would it be wise to hold off adopting until all browsers support it?

~~~
tonyonodi
You'll get an errror :) (probably a syntax error)

You don't need to hold off on using it but you should definitely use a
compiler like Babel[1] to compile your ES6 code to ES3 for compatibility.

[1] [https://babeljs.io/](https://babeljs.io/)

~~~
mercer
Shouldn't ES5 be god enough at this point (honest question)?

~~~
SiVal
Yes, in most cases. As always, the pro way to do it is to examine the browser
statistics for your target market, decide which browsers you will/won't
support, and build and test for those browsers. If you don't want to go to all
that effort for your smaller project, the bottom line is that most developers
today end up targeting ES5.

------
joshontheweb
Is there a resource that tells me which of these features are available in the
latest stable Node version?

~~~
DCoder
[https://kangax.github.io/compat-
table/es6/#node5](https://kangax.github.io/compat-table/es6/#node5)

------
s84
Didn't realize arrow functions preserver this! Now using arrow functions.

------
kclay
This will come in handy, thanks.

------
overcast
String interpolation, classes, promises, and parameter stuffs. A tear rolls
down my cheek.

------
lukasm
Is there a similar thing for coffescript?

~~~
grawlinson
Less and less people are using CoffeeScript due to ECMA2015/ES6 being released
with the large majority of functionality that CoffeeScript was created for.

You're probably better off just switching to ES6, but that's just my opinion.

------
jbeja
Who is in charge of ES6 design? Is awful.

------
z3t4
"Require" is the reason why we now have a module for just about anything in
Node.JS. I even think Kevin Dangoor or whoever invented it should get the
Nobel prize. But then the ES committee choose to use paradigms from year 1970.
I cry every time someone use import instead of require in JS because they miss
out why globals are bad, modularity is good, and the JS API philosophy (super
simple objects with (prototype) methods).

~~~
tlrobinson
I'm not sure I understand. ES6 modules are basically equivalent to "require".
`import foo from "foo";` is the same as `var foo = require("foo");`

Yes, it was Kevin Dangoor who started the CommonJS (originally "ServerJS")
project and led many of the discussions. Kris Kowal and many others were
instrumental as well. This is probably the pivotal mailing list thread for
what became CommonJS modules:
[https://groups.google.com/forum/#!topic/commonjs/Gr72Bc8Twzc](https://groups.google.com/forum/#!topic/commonjs/Gr72Bc8Twzc)

I may have written the first implementation...
[https://github.com/tlrobinson/narwhal/commit/f960f7902fb9099...](https://github.com/tlrobinson/narwhal/commit/f960f7902fb90994e0081a1afe8ce6033e2639bc)
(RIP Narwhal!)

~~~
z3t4
The main technical difference is that you can not have scoped imports. The
main impact though, is that many will use a hammer on screws, meaning; people
used to "other tools", can now do so (ES6: import, class, etc). While require
teaches you to use the electrical screwdriver.

~~~
tlrobinson
Are you saying you can't do function-scoped imports ("require" inside a
function)? I rarely see that used and it's not available in any other language
I can think of.

~~~
z3t4
Yes. It makes things so much simpler. Your program do not have to be complex!
It can exist entirely of functions that do not depend on their outer scope.
You can basically change everything around them and the function will still
work the same. And you do not have to look outside the function to understand
what it does. You only have to know about the standard objects witch in
JavaScript (ES5) is Math, Date, JSON and Error. Everything else is "required"
when needed.

~~~
tlrobinson
That's still true but on the module level. If your module is so large that
it's hard to keep track of the imports/requires then you should probably split
the module up.

I really don't think require-ing within individual functions is a common or
good practice. Can you point me to an open source project that does that?

~~~
z3t4
A module is already scoped in node.js. It would be nice to have scoped require
in the browser too, instead of just global import.

Splitting up a program, or module, into (more) modules does not make it
simpler, rather contrary, it makes it more complex! Unless it's a fully
decoupled abstraction reusable in other projects.

An example of require-ing within individual functions: A function to send
notifications to e-mail or SMS ... It makes more sense to require the SMTP or
SMS module in those functions, then somewhere else.

~~~
tlrobinson
ES6 modules do get their own scope in the browser. That's kind of the point of
them.

------
sectofloater
This will likely get downvoted - but I have just realized how much I was
underestimating the privilege of developing apps in Dart instead of
JavaScript. Dart had none of the mentioned idiosyncrasies from day one, all
the features, and has a lot of other stuff (like async/await, yield, mixins,
etc) to offer. Its tooling is very simple and powerful, and the overall
experience is really nice - when there is a problem, it's always in the logic
of my code, and not things like some weird implicit conversions that are so
common in JS land. I almost forgot how terrible JS is...

