Стандарт ECMAScript 2021 (12 редакция) выпущен 22 июня 2021 года. Вместе с ним появились новые возможности и новые синтаксические конструкции. Все эти улучшения направлены на то, чтобы сделать JavaScript надёжнее и стабильнее, чтобы разработчикам легче было делать своё дело.

Я подробно расскажу о 5 самых интересных возможностях ECMAScript 2021. Это позволит вам приступить к их использованию в своих проектах, что упростит вам работу и улучшит ваш код. Эта статья может оказаться полезной как начинающим, так и опытным разработчикам.
Разделители разрядов чисел позволяют записывать числовые литералы с использованием символов подчёркивания, что улучшает читабельность чисел. Система автоматически удаляет эти символы при подготовке кода к запуску. В следующем коде демонстрируется пример использования разделителей.
Новый метод строковых объектов
Метод
Рассмотрим пример:
Если все промисы были отклонены — будет возвращён объект
В ECMAScript 2021 появились три новых оператора, которые представляют собой комбинацию оператора присваивания и логических операторов.
Оператор
Этот оператор работает по сокращённой схеме вычислений. Он эквивалентен следующему выражению, в котором используется логический оператор ИЛИ:
Оператор
Оператор
Оператор
Свойства и методы экземпляров классов в JavaScript, по умолчанию, общедоступны. Но теперь можно создавать приватные методы и свойства с использованием префикса
Приватные методы доступа к свойствам объектов — это приватные геттеры и сеттеры. Геттер позволяет получить значение свойства, а сеттер позволяет назначить свойству значение.
Объявить приватный геттер можно так:
Так можно объявить приватный сеттер:
Вот как ими пользоваться:
Теперь вы знаете, как пользоваться некоторыми новыми возможностями JavaScript ES12 (ECMAScript 2021). А значит — пришло время применить эти знания на практике.
Пользуетесь ли вы возможностями JavaScript ES12 в своих проектах?


Я подробно расскажу о 5 самых интересных возможностях ECMAScript 2021. Это позволит вам приступить к их использованию в своих проектах, что упростит вам работу и улучшит ваш код. Эта статья может оказаться полезной как начинающим, так и опытным разработчикам.
1. Разделители разрядов чисел
Разделители разрядов чисел позволяют записывать числовые литералы с использованием символов подчёркивания, что улучшает читабельность чисел. Система автоматически удаляет эти символы при подготовке кода к запуску. В следующем коде демонстрируется пример использования разделителей.
// Десятичное число, разряды которого разделены символом подчёркивания. let n1 = 1_000_000_000; console.log(n1); // Выведет: 1000000000 // Десятичное число, разряды которого разделены символом подчёркивания. let n2 = 1_000_000_000.150_200 console.log(n2); // Выведет: 1000000000.1502 // Шестнадцатеричное число, байты которого разделены символом подчёркивания. let n3 = 0x95_65_98_FA_A9 console.log(n3); // Выведет: 641654651561 // BigInt-число, разряды которого разделены символом подчёркивания. let n4 = 155_326_458_156_248_168_514n console.log(n4); // This will print: 155326458156248168514n
2. Метод String.prototype.replaceAll()
Новый метод строковых объектов
replaceAll() позволяет заменить на что либо все вхождения подстроки в строке. При использовании строкового метода replace() осуществляется лишь замена первого вхождения искомого значения. А метод replaceAll() позволяет заменить все вхождения такого значения. Вот пример:// Объявляем константу, хранящую некое строковое значение. const orgStr = 'JavaScript, often abbreviated as JS, is a programming language that conforms to the ECMAScript specification. JavaScript is high-level, often just-in-time compiled and multi-paradigm.'; // Для т��го чтобы заменить в исходной строке лишь первое вхождение искомой подстроки и сформировать новую строку - воспользуемся методом replace(). let newStr = orgStr.replace('JavaScript', 'TypeScript'); console.log(newStr); // Для замены всех вхождений искомой строки воспользуемся методом replaceAll(). let newStr2 = orgStr.replaceAll('JavaScript', 'TypeScript'); console.log(newStr2);
3. Метод Promise.any() и объект AggregateError
Метод
Promise.any() можно назвать полной противоположностью метода Promise.all(). Promise.any(), при передаче ему итерируемого объекта с промисами, возвращает промис со значением первого успешно выполненного промиса. Если ни один из промисов не разрешён — метод возвращает сведения об ошибках, в частности — объект AggregateError. А Promise.all() ждёт разрешения всех промисов. Есть и другие методы объекта Promise. Например — Promise.allSettled(), который ожидает успешного завершения или отклонения всех переданных ему промисов.Рассмотрим пример:
// Создаём объект Promise. const promise1 = new Promise((resolve, reject) => { // Разрешить промис через 2 секунды. setTimeout(() => resolve("The first promise has been resolved."), 2000); }); // Создаём объект Promise. const promise2 = new Promise((resolve, reject) => { // Разрешить промис через 1 секунду. setTimeout(() => resolve("The second promise has been resolved."), 1000); }); // Создаём объект Promise. const promise3 = new Promise((resolve, reject) => { // Разрешить промис через 3 секунды. setTimeout(() => resolve("The third promise has been resolved."), 3000); }); (async function () { const data = await Promise.any([promise1, promise2, promise3]); // Выводим данные, возвращённые из первого разрешённого промиса. console.log(data); // Предыдущая команда выведет следующее: The second promise has been resolved. })()
Если все промисы были отклонены — будет возвращён объект
AggregateError, содержащий сведения об ошибках. Обратитесь к следующему примеру для того чтобы разобраться с тем, как обрабатывать подобные ошибки:// Создаём объект Promise. const promise1 = new Promise((resolve, reject) => { // Отклонить промис через 1 секунду. setTimeout(() => reject("The first promise has been rejected."), 1000); }); // Создаём объект Promise. const promise2 = new Promise((resolve, reject) => { // Отклонить промис через 500 миллисекунд. setTimeout(() => reject("The second promise has been rejected."), 500); }); // Попытаемся выполнить промисы. (async function () { try { const data = await Promise.any([promise1, promise2]); console.log(data); } catch (error) { // Если все промисы отклонены, мы попадём в этот блок try-catch, где // можно будет обработать ошибки, с которыми завершилась работа промисов. console.log("Error: ", error); } })();
4. Логические операторы присваивания
В ECMAScript 2021 появились три новых оператора, которые представляют собой комбинацию оператора присваивания и логических операторов.
- Логический оператор присваивания ИЛИ (OR):
||=. - Логический оператор присваивания И (AND):
&&=. - Логический оператор присваивания с проверкой значений на
nullиundefined:??=.
▍4.1. Оператор ||=
Оператор
||= принимает два операнда и назначает правый операнд левому только в том случае, если левый операнд является ложным. Вот пример:// Оператор ||= проверит, не является ли ложным (0) значение songsCount. // Если это так, правый операнд будет записан в переменную, находящуюся в левой части выражения. let myPlaylist = {songsCount: 0, songs:[]}; myPlaylist.songsCount ||= 100; console.log(myPlaylist); // Выведет: {songsCount: 100, songs: Array(0)}
Этот оператор работает по сокращённой схеме вычислений. Он эквивалентен следующему выражению, в котором используется логический оператор ИЛИ:
a || (a = b)
▍4.2. Оператор &&=
Оператор
&&= присваивает правый операнд левому только в том случае, если значение, находящееся слева, является истинным. Рассмотрим пример:// Оператор &&= проверит, является ли значение filesCount истинным. // Если это так - правый операнд будет присвоен левому. let myFiles = {filesCount: 100, files:[]}; myFiles.filesCount &&= 5; console.log(myFiles); // Выведет: {filesCount: 5, files: Array(0)}
Оператор
&&= тоже работает по сокращённой схеме вычислений. Этот оператор эквивалентен следующему выражению, в котором используется логический оператор И:a && (a = b)
▍4.3. Оператор ??=
Оператор
??= присвоит правый операнд левому только в том случае, если левый оператор представлен значением null или undefined. Например:// Оператор ??= проверит, равняется ли lastname null или undefined. // Если это так - правый операнд будет присвоен левому. let userDetails = {firstname: 'Katina', age: 24} userDetails.lastname ??= 'Dawson'; console.log(userDetails); // Выведет: {firstname: 'Katina', age: 24, lastname: 'Dawson'}
5. Приватные методы экземпляров классов и методы доступа к свойствам
Свойства и методы экземпляров классов в JavaScript, по умолчанию, общедоступны. Но теперь можно создавать приватные методы и свойства с использованием префикса
#. Доступны они только изнутри экземпляра класса. Вот как пользоваться приватными методами:// Создадим класс User. class User { constructor() {} // Приватный метод можно создать, поместив '#' перед // именем метода. #generateAPIKey() { return "d8cf946093107898cb64963ab34be6b7e22662179a8ea48ca5603f8216748767"; } getAPIKey() { // Обратиться к приватному методу можно, поставив '#' перед // именем метода. return this.#generateAPIKey(); } } const user = new User(); const userAPIKey = user.getAPIKey(); console.log(userAPIKey); // Выведет: d8cf946093107898cb64963ab34be6b7e22662179a8ea48ca5603f8216748767
Приватные методы доступа к свойствам объектов — это приватные геттеры и сеттеры. Геттер позволяет получить значение свойства, а сеттер позволяет назначить свойству значение.
Объявить приватный геттер можно так:
get #newAccountPassword() {}
Так можно объявить приватный сеттер:
set #generateAccountPassword(newPassword) {}
Вот как ими пользоваться:
// Создадим класс Str. class Str { // Приватные свойства можно создавать, помещая '#' // перед их именами. #uniqueStr; constructor() {} // Приватный сеттер можно создать, поместив '#' перед // его именем. set #generateUniqueStringByCustomLength(length = 24) { const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; let randomStr = ""; for (let i = 0; i < length; i++) { const randomNum = Math.floor(Math.random() * characters.length); randomStr += characters[randomNum]; } this.#uniqueStr = randomStr; } // Общедоступный сеттер set setRandomString(length) { this.#generateUniqueStringByCustomLength = length; } // Приватный геттер можно создать, поместив '#' перед // его именем. get #fetchUniqueString() { return this.#uniqueStr; } // Общедоступный геттер get getRandomString() { return this.#fetchUniqueString; } } const str = new Str(); // Вызываем общедоступный сеттер, который обратится к приватному сеттеру, // находящемуся в том же объекте, что и он. str.setRandomString = 20; // Вызываем общедоступный геттер, который обратится к приватному геттеру, // находящемуся в том же объекте, что и он. const uniqueStr = str.getRandomString; console.log(uniqueStr); // Выводит случайную строку каждый раз, когда геттер вызывают после вызова сеттера
Итоги
Теперь вы знаете, как пользоваться некоторыми новыми возможностями JavaScript ES12 (ECMAScript 2021). А значит — пришло время применить эти знания на практике.
Пользуетесь ли вы возможностями JavaScript ES12 в своих проектах?

