It is difficult to keep up with the
innovations of different versions of ECMAScript, and even more difficult to find useful examples of their application without digging through the mountains of information. Therefore, today we publish the translation of the material, the author of which analyzed 18 new features of ECMAScript, including those that are already in the ES2016 and ES2017 standards, and also those that should appear in the ES2018 standard. The author of this article promises that everyone who reads it will learn a lot of interesting and useful things about new features of JavaScript.

ECMAScript 2016
â–Ť1. Array.prototype.includes ()
The
includes
method is a simple method of objects of the
Array
type, which allows you to find out if there is a certain element in the array (it, unlike
indexOf
, is also suitable for working with
NaN
values).
ECMAScript 2016 (ES7) - an example of using Array.prototype.includes ()')
It is interesting that at first they wanted to call this method
contains
, but it turned out that this name was already used in Mootools, as a result, it was decided to use the name
includes
.
â–Ť2. Infix exponentiation operator
Mathematical operations, such as addition and subtraction, are implemented in JavaScript using infix operators, such as, respectively, “
+
” and “
-
”. There is also an infix operator that has found wide application in programming, which is used for exponentiation. Such an operator, looking like "
**
", was introduced in ECMAScript 2016, it can serve as a replacement for
Math.pow()
.
ECMAScript 2016 (ES7) - use infix exponentiation operatorECMAScript 2017
▍1. Object.values ​​()
The
Object.values()
method is a new function that is similar to
Object.keys()
, but returns all the values ​​of the object's own properties, excluding any values ​​in the prototype chain.
ECMAScript 2017 (ES8) - using Object.values ​​()▍2. Object.entries ()
The
Object.entries()
method is similar to the
Object.keys()
method, but instead of returning only the keys, it returns both keys and values ​​as an array. This simplifies the execution of operations involving the use of objects in cycles, or operations to convert ordinary objects into objects of type
Map
.
Here is the first example of using this method.
ECMAScript 2017 (ES8) - using Object.entries () in loopsHere is a second example.
ECMAScript 2017 (ES8) - using Object.entries () to convert an object of type Object to an object of type Mapâ–Ť3. Addition of lines to the set length
Objects of type
String
now have two new methods:
String.prototype.padStart()
and
String.prototype.padEnd()
. They allow you to attach to the lines, at their beginning or end, a number of characters to supplement the lines to a given length.
'someString'.padStart(numberOfCharcters [,stringForPadding]); '5'.padStart(10) // ' 5' '5'.padStart(10, '=*') //'=*=*=*=*=5' '5'.padEnd(10) // '5 ' '5'.padEnd(10, '=*') //'5=*=*=*=*='
This is convenient if you want to align the text, for example, when outputting to the console.
3.1 Example of working with padStart ()
In the following example, we have a list of numbers of different lengths. We want to add to the beginning of these numbers "0", and, thus, to make all of them consisting of 10 digits. It is necessary to accurately display them on the screen. In order to solve this problem, we can use the
padStart(10, '0')
command.
ECMAScript 2017 - an example of using padStart ()3.2 An example of working with padEnd ()
The
padEnd()
method is very useful when displaying a set of lines of different lengths that need to be aligned along the right edge of the page.
The following example shows how to use the
padEnd()
,
padStart()
, and
Object.entries()
to form strings that look good when displayed on the screen.
ECMAScript 2017 - an example of using padEnd (), padStart () and Object.Entries ()3.3. Using padStart () and padEnd () with emoticons and other double-byte characters
Emoticons and other two-byte characters are represented in Unicode encoding with sequences of several bytes. Therefore, the
padStart()
and
padEnd()
methods do not work with them as expected.
For example, suppose we want to make the length of the
heart
string equal to 10 characters by adding an emoticon
️
to it. The result, with the usual approach, will look like this:
// , 5 2 , , , , 'heart'.padStart(10, "️"); // '️️heart'
The problem here is that the heart with which we want to add a string is represented by the two-byte code
'\u2764\uFE0F'
. The word
heart
has a length of 5 characters and to supplement this line to length 10 we have only 5 free places. As a result, JS adds two emoticons to the string, using the code
'\u2764\uFE0F'
, which occupies four free spaces, which gives two heart icons. The last free space is filled with the first byte, the symbol with the code
'\u2764'
, which just gives the heart that looks different from the rest.
Here , by the way, is a page that can be used to work with Unicode characters.
â–Ť4. Object.getOwnPropertyDescriptors ()
This method returns all information (including information about getters and setters) for all properties of a given object. The main reason for adding this method is to allow small copies of objects to be created and to clone objects, creating new objects, while copying, among other things, getters and setters. The
Object.assign()
method does not know how. It allows you to make small copies of objects, but does not work with their getters and setters.
The following examples show the difference between
Object.assign()
and
Object.getOwnPropertyDescriptors()
, and also demonstrate how to use
Object.defineProperties()
to copy the original
car
object to a new object,
ElectricCar
. Here you can see that through the use of
Object.getOwnPropertyDescriptors()
, the
discount
function, which plays the role of both the getter and the setter, is also copied to the target object.
So, until
Object.getOwnPropertyDescriptors()
copying objects looked like this. Here you can see that when copying an object, data about getters and setters is lost.
Copying objects using Object.assign ()Here's what the execution of the same operation looks like, but already using
Object.getOwnPropertyDescriptors()
.
ECMAScript 2017 (ES8) - using Object.getOwnPropertyDescriptors ()â–Ť5. Trailing commas in function parameters
This is a small update that allows you to put a comma after the last parameter of the function. Why do you need it? For example, in order to help when working with tools like
git blame
, eliminating developers who make changes to the code from having to change (without much need in this case) the lines written by those who worked on this code before.
The following example shows the problem of editing the code and its solution using a comma, which is located behind the last parameter of the function.
ECMAScript 2017 (ES8) - a comma, set after the last parameter of the function, facilitates code editingâ–Ť6. Async / Await design
I would call this innovation the most important and the most useful. Asynchronous functions allow you to get rid of the so-called “hell callbacks” and improve the appearance and readability of the code.
The
async
tells the JavaScript interpreter that the function declared with this keyword needs to be perceived in a special way. The system pauses, reaching the
await
keyword in this function. She considers that the expression after
await
returns a promise and waits for permission or rejection of this promise before continuing.
In the following example, the
getAmount()
function calls two asynchronous functions,
getUser()
and
getBankBalance()
. This can be done in promise, but using the async / await construction makes it easier and more elegant to solve this problem.
ECMAScript 2017 (ES 8) - a simple example of using the Async / Await construction6.1. Asynchronous Functions and Promise Returns
If you expect a result from a function declared using the
async
, you will need to use the expression promis
.then()
to get this result.
In the following example, we want to output the result to the console using the
console.log()
command, but this needs to be done outside the
doubleAndAdd()
function. Therefore, we need to wait using
.then()
to transfer the result to
console.log()
.
ECMAScript 2017 (ES 8) - demonstration of return promise with the async / await construct6.2. Parallel function calls using async / await
In the previous example, we use the
await
keyword twice, each time waiting for the operation to complete for one second (total waiting time is 2 seconds). Instead, we can parallelize the execution of tasks, since
a
and
b
are independent of each other. This can be done using the
Promise.all()
construct.
ECMAScript 2017 (ES 8) - using Promise.all for parallel execution of await commands6.3. Error handling when using async / await construction
There are various ways to handle errors when using the async / await construction.
Option 1: use try / catch inside a function
ECMAScript 2017 - use try / catch inside async / await constructionOption 2: use catch in each await expression
Since each
await
expression returns a promise, you can catch errors in each such expression.
ECMAScript 2017 - Use the catch construct with each await expressionOption 3: use the catch construct for the entire async / await function
ECMAScript 2017 - interception of errors in the entire asynchronous functionECMAScript 2018
ECMAScript 2018 is now at the stage of final draft, the standard is expected in June-July 2018. All features discussed below are at Stage-4 and will become part of ECMAScript 2018.
â–Ť1. Shared memory and atomic operations
Shared memory and atomic operations are a terrific, highly advanced feature affecting the core of JS engines.
The main idea of ​​this feature is to allow JS-developers to write high-performance parallel applications, to give them the ability to manage memory independently, without giving all the aspects of this task to the JS engine.
This is implemented using a global object of a new type called
SharedArrayBuffer . Its main task is to store data in a shared memory space. As a result, such data can be shared between the main JS stream and web worker threads.
Until now, if we needed to organize data exchange between the main thread and the web worker, we had to create copies of the data and send them using the
postMessage()
function. Now everything will not be the same as before.
By using
SharedArrayBuffer
different streams can access data almost instantly. However, sharing memory from different streams can cause a race condition. In order to avoid this state, a global
Atomics object is provided. It provides various methods for blocking shared memory for the duration of operations with it from a particular thread. It also provides methods for safely updating data in shared memory.
Usually this feature is not recommended to be used directly, saying that it would be better to use libraries built on the basis of the
SharedArrayBuffer
. However, such libraries have not yet been written.
If you are interested in this topic -
here ,
here and
here - some useful materials.
â–Ť2. Eliminate the limitations of tagged pattern strings
To begin with, let's look at the concept of “tagged template string” (or “tagged template”) in order to better understand this new feature.
In ES2015 + there is a feature called a tagged template that allows developers to customize string interpolation. For example, with the standard approach, it looks like this.
Standard use of patterned stringsWhen using tagged templates, you can write a function that takes, as parameters, an invariable part of a string literal, for example,
[ 'Hello ', '!' ]
[ 'Hello ', '!' ]
and substitution variables, for example,
[ 'Raja']
. For example, let it be a
greet
function. Such a function can return what the developer needs.
The following example shows how our own tag expression, a function, appends a greeting to a string based on the time of day (for example, “Good Morning!” Or “Good afternoon”) and returns the finished string.
An example of a tagged expression, a function that demonstrates custom string additionAfter learning about tagged template strings, many people seek to use this feature in various fields, for example, to work with commands in a terminal or when creating a URL to execute HTTP requests. However, there is one important limitation to consider. It lies in the fact that ES2015 and ES2016 allow you to use only control sequences like
"\u" (unicode)
,
"\x"(hexadecimal)
, which form something that is understandable to the system, for example,
`\u00A9`
or
\u{2F804}
or
\xA9
.
Therefore, if there is a tagged function, inside which rules from another area are used (for example, when working with a terminal), where you may need to use something like
\ubla123abla
that does not look like a correct code from the system’s point of view, an error message will appear.
In ES2018, restrictions are relaxed. Now you can use constructions that look like wrong control sequences, returning values ​​in the object, one property of which (“cooked” in our example) contains
undefined
, and the second (“raw”) contains what we need.
function myTagFunc(str) { return { "cooked": "undefined", "raw": str.raw[0] } } var str = myTagFunc `hi \ubla123abla`;
â–Ť3. DotAll regular expression flag
Now, when using regular expressions, although it is believed that the dot character matches any single character, it does not match newline characters like
\n
\r
\f
and so on.
For example, before this innovation, everything looked like this:
/first.second/.test('first\nsecond'); //false
With this improvement, the dot now matches absolutely any character. In order for the old regular expressions to continue to work as before, when creating regular expressions that follow the new rules, you need to use the
\s
flag.
//ECMAScript 2018 /first.second/s.test('first\nsecond'); //true - /s
Here is the API of this
proposal from the documentation.
ECMAScript 2018 - now, thanks to the / s flag, you can make the dot in regular expressions match absolutely all characters, including \ nâ–Ť4. Capturing Named Groups in Regular Expressions
This enhancement is a useful regular expression feature that exists in other languages ​​like Python and Java. These are named groups. This feature allows developers to write regular expressions with assignment of names (identifiers) in the format
(?<name>...)
for groups. This name makes it easier to work with groups.
4.1. Basic example of working with named groups
In the following example, we use the names
(?<year>)
,
(?<month>)
and
(?day)
to group the different parts of the date we work with using a regular expression. The final object in this approach will contain the
groups
property, which will have the
year
,
month
and
day
properties with the corresponding values.
ECMAScript 2018 - an example of working with named groups4.2. Using named groups inside a regular expression
We can use constructions of the form
\k<group name>
to refer to groups within the regular expression itself. This technique is demonstrated in the following example.
ECMAScript 2018 - using named groups within a regular expression using the \ k <group name> construct4.3. Using Named Groups in String.prototype.replace ()
Now the ability to use named groups is built into the
replace()
string method. This allows, for example, to organize a permutation of words in lines. For example, here's how to change the string
"firstName, lastName"
to
"lastName, firstName"
.
ECMAScript 2018 - using named regular expression groups in the string replace () methodâ–Ť5. Working with object properties using the rest operator
The rest operator, which looks like three points, allows you to retrieve the properties of an object that have not yet been extracted from it.
5.1. Retrieving from the object only the necessary properties
ECMAScript 2018 - Destructuring an Object Using the Rest Operator5.2. Remove unwanted properties of objects
ECMAScript 2018 - removing unnecessary properties of objectsâ–Ť6. Working with properties of objects using the spread operator
The spread operator also looks like three points. The difference between it and the rest operator is that it is used to create new objects.
The spread operator is used on the right side of an expression with an assignment sign. The rest operator is used on the left side of the expression.
ECMAScript 2018 - creating an object using the rest operatorâ–Ť7. Retrospective check in regular expressions
A retrospective check in regular expressions allows you to find out if a certain string exists immediately before some other string.
Now, in order to make a positive retrospective test, you can use a group of the form
(?<=…)
(question mark, less sign and equal sign).
Further, you can use a group of the form
(?>!…)
(question mark, less sign, exclamation mark) to perform a negative retrospective check. The search with this approach is continued only if there is no expression in brackets to the left of the current position in the text.
Consider an example of a positive retrospective test. Suppose we need to check whether the
#
character is
#
front of the word
winning
(that is, we are interested in the construction of the form
#winning
), while we need the regular expression to return only the string "winning". Here is how you can achieve this.
ECMAScript 2018 - using the construct (? <= ...) for positive retrospective verificationConsider an example of negative retrospective verification. Suppose we need to extract from the string the numbers preceded by the
€
sign, but not the
$
sign. Here's how to do it.
EMAScript 2018 - using the construct (? <! ...) for negative retrospective verificationâ–Ť8. Using Unicode escape sequences in regular expressions
Previously, writing regular expressions to analyze Unicode characters was not easy. Constructions of the form
\w
,
\W
,
\d
helped only in working with Latin characters and numbers. And what about the characters of other languages, like Hindi or Greek?
It is in such situations that the
use of Unicode escape sequences in regular expressions will be useful. Unicode is known to have metadata for each character; this metadata is used to group or describe the characteristics of different characters.
Unicode ( — हिन्दी, , , )
Script
Devanagari
, ,
Script_Extensions
, .
Script=Devanagari
.
Unicode-
Devanagari , , , , .
ECMAScript 2018
\p{Script=Devanagari}
. .
ECMAScript 2018 — Unicode-,
Script_Extensions
(
Script
)
Greek
.
Script_Extensions=Greek
Script=Greek
.
\p{Script=Greek}
.
ECMAScript 2018 —, Unicode
Emoji
,
Emoji_Component
,
Emoji_Presentation
,
Emoji_Modifier
,
Emoji_Modifier_Base
true
. ,
Emoji
.
,
\p{Emoji}
\p{Emoji_Modifier}
. .
ECMAScript 2018 —, , , P (
\P
) p (
\p
) .
â–Ť9. Promise.prototype.finally()
finally()
—
Promise
. ,
resolve()
reject()
, , , , .
finally()
- , .
.
ECMAScript 2018 — finally() resolve()ECMAScript 2018 — finally() reject()ECMAScript 2018 — finally()ECMAScript 2018 — finally() catch()▍10.
— . , .
for-await-of
, , ( , ) . , .
ECMAScript 2018 — for-await-ofResults
ES2016, ES2017 ES2018, . , , JavaScript .
! ES2016, ES2017 ES2018 ?
