ES6 review at 350 points. Part one

Original author: Nicolas Bevacqua
  • Transfer
My 24-entry ES6 in Depth series of notes describes most of the syntax changes and innovations in ES6. In this publication, I will summarize everything stated in previous articles to give an opportunity to look again at everything together. I also added links to my blog so that, if necessary, I could immediately see more.



I heard you like bulleted lists, so here's an article with a list that consists of several hundred elements.

First, I’ll give a table of contents so that it is clear what will be discussed. Obviously, a table of contents is also an unordered list. Please note: if you want to delve deeper into this topic, read the entire series of articles and independently “dig through” the ES6 code.

Content

● Introduction
● Tooling
● Assignment Destructing
● Spread Operator and Rest Parameters
● Arrow functions
● Template strings
● Object literals
● Classes
● Let and Const
● Symbols
● Iterators
● Generators
● Promises
● Maps
● WeakMaps
● Sets
● WeakSets
● Proxies
● 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 ES6 specification was approved in June 2015 (hence ES2015).
● Future language versions will be named according to the ES [YYYY] pattern, for example ES2016 for ES7.
o Annual release cycle, irreversible changes begin to operate 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 template [YYYY] to refer to new 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.

Toolkit

● To use ES6 today, you need a JavaScript-to-JavaScript transporter.
● The transpilers have come and will remain because:
o they provide the ability to compile the code of the new version of the language into the code of the old version;
o we will transpose ES2016 and ES2017 to ES6, etc., when browser support gets better;
o we need improved source mapping functionality;
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 pipe ES6 to ES5 for static builds.
● Use babelify to embed babel in your grunt, gulp, or npm run build process.
● Use nodejs of weight 4.xx or higher - there is very decent support for ES6 (thanks v8).
● Use babel-node with any version of node.js - it will transpile modules in ES5.
● Babel has a growing 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 aliases:
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 an error var {foo: {bar}} = {}.
● This also works for arrays, [a, b] = [0, 1] will return a: 0 and b: 1.
● You can skip the elements in the array, [a ,, b] = [0, 1, 2], we get a: 0 and b: 2.
● Variables can be interchanged without resorting to the third “aux” variable, [a, b] = [b, a].
● You can also use destructuring in function parameters:
o assignment of default values ​​function foo (bar = 2) {};
o these values ​​can also be objects function foo (bar = {a: 1, b: 2}) {};
o you can destruct bar completely: function foo ({a = 1, b = 2}) {};
o if nothing was passed, 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 the method signature is declared as function foo (... everything) {};
o everything is an array with all parameters passed to foo;
o you can name 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 indicated by ... syntax:
o cancels the need to apply when calling methods, fn (... [1, 2, 3]) - the same as fn (1, 2 , 3);
o simplified concatenation: [1, 2, ... [3, 4, 5], 6, 7];
o allows you to mold array-like elements or collections into arrays [... document.querySelectorAll ('img')];
o 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 a function param => returnValue.
● Useful for functional programming, [1, 2] .map (x => x * 2).
● There are several different ways to use it (it will take some time to develop a habit):
○ p1 => expr is great if there is only one parameter;
○ p1 => expr has an implicit return statement for expr;
○ to implicitly return an object, you need to wrap it in parentheses () => ({foo: 'bar'}), otherwise you get an error;
○ parentheses are needed when you have 0, 2 or more parameters () => expr or (p1, p2) => expr;
○ curly brackets on the right side represent a code block, which may contain several instructions () => {};
○ when using this syntax, there is no implicit return, you need to write it () => {return 'foo'}.
● You cannot statically give a arrow function a name, but performance tests are much better for most methods without a name.
● Arrow functions are tied 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 methods of a “reflection” type.
● Read ES6 Arrow Functions in Depth.

Template strings

● Strings can be declared using backticks (`) in addition to single and double.
● Backquoted strings are pattern strings.
● Template strings can be multi-line.
● Template strings allow intermediate calculations of `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 the marked templates to change the logic for calculating intermediate values:
○ add the prefix fn 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 pattern string;
○ possible examples of use: cleaning input expressions from unnecessary data, parsing parameters, etc.
● Template strings are generally 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} - an abbreviated form for writing a property – value pair.
● Computed property names: {[prefix + 'Foo']: 'bar'}, where prefix: 'moz' returns {mozFoo: 'bar'}.
● You cannot try to use the two previous features at the same time, the entry {[foo]} is invalid.
● Method definitions can be made more concise using the following syntax: {foo () {}}.
● See also the Object section .
● Read the ES6 Object Literal Features in Depth.

Classes

● Not “traditional” classes, but syntactic sugar on top of the prototype inheritance mechanism.
● The syntax is similar to declaring class Foo {} objects.
● Instance methods new Foo (). Bar are declared using the simplified syntax of the object literals class Foo {bar () {}}.
● Static methods - Foo.isPonyFoo () - need a prefix, the keyword static class Foo {staticisPonyFoo () {}}.
● constructor method class Foo {constructor () {/ * initialize instance * /}.
● 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, not a lexical one, 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 VMZ:
○ starts at the beginning of the block in which let foo is declared;
○ ends at the point in the code where the let foo declaration takes place (here the “climb” does not matter);
○ attempts to access or define foo inside the VMZ (before the let foo statement is executed) will lead to an error;
○ helps reduce the number of mysterious bugs in which the value of a variable undergoes changes before its declaration.
● const also has a block scope, “rise” and follows the semantics of the VMZ.
● The const variables must be declared using the initializer const foo = 'bar'.
● Defining const after initialization causes a silent error (or non-silent error in strict mode).
● Const variables do not make a variable immutable:
○ const foo = {bar: 'baz'} means that foo will always refer to the object on 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 quit.
● Designed to correct errors when you redefine a variable and lose reference to the original object.
● In ES6, functions have a block scope:
○ prevent data leakage through the "pop-up" mechanism {let _foo = 'secret', bar = () => _foo; };
○ Do not break custom code in most situations and, as a rule, are what you need.
● Read ES6 Let, Const and the “Temporal Dead Zone” (TDZ) in Depth.

Also popular now: