December 10, 2021

Топ-5 функционала JavaScript ES12

Узнайте об удивительных возможностях, предлагаемых обновлением ECMAScript 2021.

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); // Вывод: 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); // Вывод: 155326458156248168514n

2. String.prototype.replaceAll

Функция replaceAll()прототипа String позволяет заменить все экземпляры подстроки без использования regex. Если функция replace(), используемая для строки, заменяет только первый экземпляр этого значения, функция replaceAll() обеспечивает функциональность замены всех экземпляров этого значения. Обратитесь к следующему фрагменту кода, чтобы понять, как можно использовать replaceAll().

// Объявляем переменную и храним в ней некоторое значение.
const orgStr = `JavaScript, часто сокращенно JS, - это язык \
программирования, соответствующий спецификации ECMAScript. \
JavaScript - это мультипарадигменный язык высокого уровня, \
часто компилируемый "во время выполнения"`;

// Чтобы заменить один экземпляр, используем 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 будет разрешено (зарезолвлено). С другой стороны, Promise.all() будет ждать, пока все promises не будут разрешены. Ниже приведены различия в функциях any(), all() и allSettled().

any() - Выполняется, если хотя бы одно promise будет разрешено, либо отклонится, если все промисы будут отклонены.
all() - Выполнится, если все промисы будут разрешены, и будет отклонено, если хотя бы один промис будет отклонен.
allSettled() - Выполняется, если все промисы были либо разрешены, либо отклонены.

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

// Создадим Promise. Через 2 секунды выполним первый promise.
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => resolve("Первый промис был зарезолвлен."), 2000);
});

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

// Создадим Promise. Через 3 секунд выполним третий promise.
const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => resolve("Третий промис был зарезолвлен."), 3000);
});

// Выведим данные, возвращенные из первого разрешенного Promise.
(async function () {
    const data = await Promise.any([promise1, promise2, promise3]);
    console.log(data);
})();
// На экране появится сообщение: "Второй промис был зарезолвлен".

Если все Promise будут отклонены, то будет выброшено исключение AggregateError. Посмотрите следующий фрагмент кода, чтобы понять, как можно обработать исключение.

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

// Создадим Promise. Через 500 миллисекунд будет отклонен.
const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => reject("Второй промис был отклонен."), 500);
});

// Попробуем выполнить Promises. Если все Promises будут отклонены, 
// то блок try-catch будет обрабатывать исключение.
(async function () {
    try {
        const data = await Promise.any([promise1, promise2]);
        console.log(data);
    } catch (error) {
        console.log("Error: ", error);
    }
})();
// Вывод: "Error:  AggregateError: All promises were rejected"

4. Логические операторы присваивания

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

  • Логический оператор присваивания OR ||=, записывается как ||=
  • Логический оператор присваивания AND &&=
  • Нулевой объединяющий оператор присваивания ??=

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

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

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

Этот оператор ||= эквивалентен следующему утверждению, в котором используется оператор логического ИЛИ.

a || (a = b)

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

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

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

Этот оператор &&= эквивалентен следующему утверждению, в котором используется логический оператор "И".

a && (a = b)

4.3. Нулевой объединяющий оператор присваивания

Оператор нулевого слияния ??= присваивает правый операнд левому операнду только в том случае, если левый операнд равен null или undefined. Ниже приведен фрагмент кода, чтобы узнать, как можно использовать данный оператор.

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

Этот оператор ??= эквивалентен следующему утверждению, в котором используется оператор нулевого объединения.

a ?? (a = b)

5. Приватные методы и аксессоры класса

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

// Let's create a class named User.
class User {
// Приватные методы можно создать, добавив '#' перед именем метода.  
    #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;
   // Частные сеттеры можно создать, добавив '#' перед названием
    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). Теперь вы можете приступить к внедрению вышеуказанных возможностей в свои нынешние или предстоящие проекты.

Источник: https://levelup.gitconnected.com/top-5-javascript-es12-features-you-should-start-using-now-b16a8b5353b1