My series of notes
ES6 in Depth , consisting of 24 entries, describes most of the syntax changes and innovations in ES6. In this publication, I will summarize everything stated in previous articles in order to give an opportunity to look again at everything together. I also added links to my blog, so that if necessary, you can immediately see more details.

I heard you like bulleted lists, so hereβs an article with a list of several hundred items.
To begin with, I will provide a table of contents so that it is clear what is being discussed. Obviously, the table of contents is also an unnumbered list. Please note: if you want to delve deeper into this topic,
read the entire cycle of articles and independently βpickβ the ES6 code.
')
Contentβ Introduction
β Toolkit
β Assignment Destructing
β Spread Operator and Rest Parameters
β Arrow functions
β Pattern lines
β Object Literals
β Classes
β Let and Const
β Characters
β iterators
β Generators
β Promises
β Maps
β WeakMaps
β Sets
β WeakSets
β Proxy
β Reflection
β Number
β Math
β Array
β Object
β Strings and Unicode
β Modules
Sorry for such a long table of contents. Getting started.
Introductionβ ES6 (also known as Harmony, es-next, ES2015) is the latest and final language specification.
β The final specification of ES6 was approved in June 2015 (therefore, ES2015).
β Future versions of the language will be named according to the ES [YYYY] pattern, for example ES2016 for ES7.
o Annual release cycle, irreversible changes begin to take effect from the next release.
o Since ES6 appeared earlier than this solution, most of us still call it ES6.
o Starting with ES2016 (ES7), we must use the ES [YYYY] template to refer to newer versions.
o The main reason for using this naming pattern is to put pressure on browser manufacturers to implement the latest updates as quickly as possible.
Toolsβ To use ES6 today, you need a JavaScript-to-JavaScript transpiler.
β Transporters came and will remain, because:
o they provide the ability to compile the code of the new language version into the code of the old version;
o we will transfer ES2016 and ES2017 to ES6, etc., when browser support gets better;
o we need improved source mapping;
o today it is the most reliable way to run ES6 code in production (despite the fact that browsers support ES5).
β Babel (transpiler) has a killer feature: human-readable output.
β Use
babel to transfer ES6 to ES5 for static builds.
β Use
babelify to embed a babel into your
grunt, gulp or npm run build process.
β Use nodejs version 4.xx or higher - there is a very decent support for ES6 (thanks to v8).
β Use babel-node with any version of node.js - it will transfer modules to ES5.
β Babel has an expanding ecosystem that already supports ES2016 and some plugins.
β Read
A Brief History of ES6 Tooling.Assignment Destructuringβ var {foo} = pony is the same as var foo = pony.foo.
β var {foo: baz} = pony is the same as var baz = pony.foo
β You can set default values, var {foo = 'bar'} = baz will return foo: 'bar' if baz.foo is undefined.
β You can drag as many properties as you like, with or without pseudonyms:
o var {foo, bar: baz} = {foo: 0, bar: 1} will give foo: 0 and baz: 1.
β You can go further: var {foo: {bar}} = {foo: {bar: 'baz'}} will give bar: 'baz'.
β You can also assign an alias to this: var {foo: {bar: deep}} = {foo: {bar: 'baz'}} will give you deep: 'baz'.
β Properties that were not found still return undefined var {foo} = {}.
β Nested properties that were not found return the error var {foo: {bar}} = {}.
β This also works for arrays, [a, b] = [0, 1] returns a: 0 and b: 1.
β You can skip elements in the array, [a ,, b] = [0, 1, 2], we obtain a: 0 and b: 2.
β Variables can be swapped without resorting to the third βauxβ variable, [a, b] = [b, a].
β You can also use destructuring in the function parameters:
o assignment of default values ββfunction foo (bar = 2) {};
o these values ββcan also be function foo objects (bar = {a: 1, b: 2}) {};
o it is possible to destructurize bar completely: function foo ({a = 1, b = 2}) {};
o if nothing was transmitted, by default we get an empty array: function foo ({a = 1, b = 2} = {}) {}.
Read
ES6 JavaScript Destructuring in Depth.Spread Operator and Rest Parametersβ Rest parameters are like arguments, only better.
o method signature is declared as function foo (... everything) {};
o everything is an array with all the parameters passed to foo;
o You can give a name to several parameters before ... everything, for example: function foo (bar, ... rest) {};
o these parameters will be excluded from ... rest;
o ... rest should be the last parameter in the list.
β Spread operator is even better than magic, it is also denoted using ... syntax:
o cancels the need to apply when calling methods, fn (... [1, 2, 3]) is the same as fn (1, 2, 3);
o simplified concatenation: [1, 2, ... [3, 4, 5], 6, 7];
o allows you to cast a mass-like elements or collections into arrays [... document.querySelectorAll ('img')];
o is also useful when
destructing [a ,, ... rest] = [1, 2, 3, 4, 5] returns a: 1 and rest: [3, 4, 5];
o makes new + .apply simple, new Date (... [2015, 31, 8]).
β Read
ES6 Spread and Butter in Depth.Arrow functionsβ A concise way to declare the function param => returnValue.
β Useful for functional programming, [1, 2] .map (x => x * 2).
β There are several different uses (it will take some time to develop a habit):
β p1 => expr is great if the parameter is one;
β p1 => expr has an implicit return statement for the expr expression;
β To implicitly return an object, you need to wrap it in parentheses () => ({foo: 'bar'}), otherwise you will get an error;
β Parentheses are necessary when you have 0, 2 or more parameters () => expr or (p1, p2) => expr;
β The curly brackets in the right part represent a block of code that can contain several instructions () => {};
β when using such syntax there is no implicit return, you need to write it () => {return 'foo'}.
β You cannot statically give the arrow function a name, but performance tests are much better for most methods without a name.
β The switch functions are bound to the lexical environment:
β this is the same this context as in the parent lexical environment;
β this cannot be changed using .call, .apply, or similar βreflectionβ -type methods.
β Read
ES6 Arrow Functions in Depth.Pattern linesβ Strings can be declared using back quotes (`) in addition to single and double quotes.
β Strings with backquotes are pattern strings.
β Pattern lines can be multi-line.
β Pattern lines allow intermediate calculations to be `ponyfoo.com is $ {rating}`, where rating is a variable.
β You can use any valid js expression to evaluate, for example: `$ {2 * 3}` or `$ {foo ()}`.
β You can use labeled patterns to change the logic for calculating intermediate values:
β add fn prefix to fn`foo, $ {bar} and $ {baz} `;
β fn is called once with template, ... expressions;
β template is ['foo,', 'and', ''], and expressions is [bar, baz];
β the result fn becomes the value of the template string;
β Possible examples of use: clearing input expressions from unnecessary data, parsing parameters, etc.
β Pattern strings are almost everywhere better than strings wrapped in single or double quotes.
β Read the
ES6 Template Literals in Depth.Object Literalsβ Instead of {foo: foo}, you can simply write {foo} - the abbreviated form of the property-value pair.
β Calculated property names: {[prefix + 'Foo']: 'bar'}, where prefix: 'moz' returns {mozFoo: 'bar'}.
β It is impossible to simultaneously try to use the two previous features, the {[foo]} entry is invalid.
β Method definitions can be made more concise with the following syntax: {foo () {}}.
β See also the
Object section
.β Read
ES6 Object Literal Features in Depth.Classesβ Not βtraditionalβ classes, but syntactic sugar on top of the prototype inheritance mechanism.
β Syntax is similar to the declaration of class Foo {} objects.
β The instance methods new Foo (). Bar are declared using the simplified
syntax of the class object
literals Foo {bar () {}}.
β Static methods - Foo.isPonyFoo () - need the prefix, the keyword static class Foo {staticisPonyFoo () {}}.
β Class Foo {constructor () {/ * initialize instance * /} constructor method.
β Prototype inheritance with simplified syntax class PonyFoo extends Foo {}.
β Read
ES6 Classes in Depth.Let and Constβ let and const are alternatives to var when declaring variables.
β let has a block scope, rather than lexical, with respect to the parent function.
β let
rises to the top of the block, while var rises to the top of the function.
β βTemporary dead zoneβ or simply VSW:
β starts at the beginning of the block where let foo is declared;
β ends at the place of the code where the let foo declaration occurs (here, βliftingβ does not matter);
β attempts to access or define foo inside the VMP (before the let foo instruction is executed) will result in an error;
β It helps to reduce the number of mysterious bugs in which the value of a variable undergoes changes before it is announced.
β const also has a block scope, βelevation,β and follows the VLM semantics.
β Const variables must be declared using the initializer const foo = 'bar'.
β The definition of const after initialization causes a silent error (or not a quiet one - in strict mode).
β The const variables do not make the variable unchangeable:
β const foo = {bar: 'baz'} means that foo will always refer to the object in the right side of the expression;
β const foo = {bar: 'baz'}; foo.bar = 'boo' will not throw an exception.
β Defining a variable with the same name will throw.
β Designed to correct errors when you override a variable and lose the reference to the original object.
β In ES6, functions have a block scope:
β prevent data leakage through the ascent mechanism {let _foo = 'secret', bar = () => _foo; };
β Do not break user code in most situations and, as a rule, are what you need.
β Read the
ES6 Let, Const and the βTemporal Dead Zoneβ (TDZ) in Depth.