ECMAScript 2021 (12-я версия) с новыми функциями и оптимизированным синтаксисом уже доступен. Обновленные спецификации были утверждены ECMA International 22 июня 2021 года. Усовершенствование стандарта должно повысить надежность JavaScript и облегчить разработчикам выполнение их задач.

Я подробно продемонстрирую 5 самых крутых функций, предлагаемых ECMAScript 2021. Используя их в своих проектах, вы подниметесь на ступеньку выше в работе с JavaScript. Статья будет полезна как начинающим, так и опытным разработчикам.

Топ-5 функций JavaScript, предлагаемых обновленным ECMAScript 2021

  1. Разделители числовых разрядов.
  2. String.prototype.replaceAll.
  3. Promise.any() и AggregateError.
  4. Операторы логического присваивания.
  5. Методы и аксессоры приватного класса.

1. Числовые разделители

Числовые разделители, добавляя символы подчеркивания в алгебраических числах, делают их более удобочитаемыми. При анализе файлов эти символы подчеркивания автоматически удаляются. Следующий фрагмент кода — наглядный пример использования числовых разделителей.

// Десятичный целочисленный литерал с цифрами, сгруппированными по тысячам.
let n1 = 1_000_000_000;
console.log(n1); // This will print: 1000000000

// Десятичный литерал с цифрами, сгруппированными по тысячам.
let n2 = 1_000_000_000.150_200
console.log(n2); // This will print: 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); // Будет выведено следующее: 155326458156248168514n

2. String.prototype.replaceAll

Функция replaceAll() в String prototype позволяет заменить все экземпляры подстроки без использования regex. Если функция replace() используется для строки, она заменяет только первый экземпляр этого значения. С другой стороны, replaceAll() обеспечивает функциональную возможность замены всех экземпляров этого значения. В следующем фрагменте кода демонстрируется, как использовать 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() сработает, если любой из промисов будет решен, тогда как Promise.all()будет ждать, пока все промисы не будут решены. Ниже приведены различия в функциях any(), all(), и allSettled().

  • any() — выполняется, если хотя бы один промис решен, и отклоняется, если все промисы отклонены;
  • all() — выполняется, если все промисы решены, и отклоняется, если хотя бы один промис отклонен;
  • allSettled() — выполняется, если все промисы либо решены, либо отклонены.

Обратите внимание на следующий фрагмент кода, чтобы узнать, как используется Promise.any().

// Создайте промис.
const promise1 = new Promise((resolve, reject) => {
// Через 2 секунды решите первый промис.
setTimeout(() => resolve("The first promise has been resolved."), 2000);
});

// Создайте промис.
const promise2 = new Promise((resolve, reject) => {
// Через 1 секунду решите второй промис.
setTimeout(() => resolve("The second promise has been resolved."), 1000);
});

// Создайте промис.
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);
// Вышеуказанная функция выведет следующее: второй промис был решен.
})();

При отклонении всех промисов будет выдано исключение AggregateError. На следующем фрагменте кода показано, как обработать это исключение.

// Создайте промис.
const promise1 = new Promise((resolve, reject) => {
// Через 1 секунду отклоните первый промис.
setTimeout(() => reject("The first promise has been rejected."), 1000);
});

// Создайте промис.
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 &&=;
  • оператор присваивания с нулевым/неопределенным значением ??=.

Они обеспечивают комбинацию логических операторов и выражений присваивания.

4.1. Логический оператор присваивания OR

Логический оператор присваивания OR ||= принимает два операнда и присваивает правый операнд левому, если левый операнд оказывается ложным. Обратите внимание на следующий фрагмент кода, демонстрирующий использование логического оператора присваивания OR.

// В данном примере ||= проверит, является ли значение songsCount ложным (0).
// Если значение ложно, правое значение будет присвоено левой переменной.
let myPlaylist = {songsCount: 0, songs:[]};
myPlaylist.songsCount ||= 100;
console.log(myPlaylist); // Будет выведено следующее: {songsCount: 100, songs: Array(0)}

Логический оператор присваивания OR выполняется по сокращенной схеме. Оператор ||= эквивалентен следующему выражению, в котором используется логический оператор OR:

a || (a = b)

4.2. Логический оператор присваивания AND

Логический оператор AND &&= присваивает правый операнд левому операнду только в том случае, если левый операнд истинен. Следующий фрагмент кода демонстрирует использование логического оператора присваивания AND.

// В данном примере &&= проверит, является ли значение filesCount истинным.
// Если значение истинно, то правое значение будет присвоено левой переменной.
let myFiles = {filesCount: 100, files:[]};
myFiles.filesCount &&= 5;
console.log(myFiles); // Будет выведено следующее:{filesCount: 5, files: Array(0)}

Логический оператор присваивания AND также выполняется по сокращенной схеме. Оператор &&= эквивалентен следующему выражению, в котором используется логический оператор AND:

a && (a = b)

4.3. Оператор присваивания с нулевым/неопределенным значением

Оператор с нулевым/неопределенным значением ??=присваивает правый операнд левому операнду, только если левый операнд равен нулю или не определен. В следующем фрагменте кода показано, как используется оператор присваивания с нулевым/неопределенным значением.

// В данном примере ??= проверит, является ли lastname null или неопределенным.
// Если значение — null или не определено, правое значение будет присвоено левой переменной.
let userDetails = {firstname: 'Katina', age: 24}
userDetails.lastname ??= 'Dawson';
console.log(userDetails); // Будет выведено следующее: {firstname: 'Katina', age: 24, lastname: 'Dawson'}

Оператор присваивания с нулевым/неопределенным значением также выполняется с сокращением схемы. Оператор ??=эквивалентен следующему выражению, в котором используется оператор с нулевым/неопределенным значением:

a ?? (a = b)

5. Методы и аксессоры приватного класса

Методы и свойства класса по умолчанию являются публичными, но приватные методы и свойства могут быть созданы с помощью хэш-префикса #. Инкапсуляция приватности была введена в обновленном ECMAScript 2021. Доступ к этим приватным методам и свойствам возможен только изнутри класса. Следующий фрагмент кода поможет понять, как использовать приватные методы.

// Давайте создадим класс с именем 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). Можете приступать к внедрению этих продвинутых функций и операторов в свои текущие и будущие проекты.

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Tara Prasad Routray, Top 5 JavaScript ES12 Features You Should Start Using Now

Предыдущая статьяЛассо- и ридж-регрессии: интуитивное сравнение
Следующая статьяКак легко и надежно реализовать модульные тесты на Python