Главная Категории Контакты Поиск

Руководство по ES2018 (ES9)

Узнай всё о ECMAScript и функциях, добавленных в ES2018 (ES9).

JavaScript·25.04.2019·читать 4 мин 🤓·Автор: Alexey Myzgin

Rest/Spread Свойства

ES6 представил концепцию rest элементов при работе с деструктуризацией массива:

const numbers = [1, 2, 3, 4, 5];
[first, second, ...others] = numbers;

и spread элементов:

const numbers = [1, 2, 3, 4, 5];
const sum = (a, b, c, d, e) => a + b + c + d + e;
const sumOfNumbers = sum(...numbers);

rest это ... слева от знака оператора присваивания; означает остальные элементы, а spread находится справа и означает распространение элементов.

ES2018 ввел то же самое, но для объектов.

Rest свойство

const { first, second, ...others } = {
  first: 1,
  second: 2,
  third: 3,
  fourth: 4,
  fifth: 5
};

first; // 1
second; // 2
others; // { third: 3, fourth: 4, fifth: 5 }

Spread свойство

Свойство spread позволяет создавать новый объект путем объединения свойств объекта, переданного после оператора распространения ...:

const items = { first, second, ...others };
items; //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }

Асинхронная итерация

Новая конструкция for-await-of позволяет нам вызывать асинхронные функции, которые возвращают промис (или массивы с кучей промисов) в цикле. Круто то, что цикл ожидает выполнение каждого промиса, прежде чем перейти к следующему циклу:

const promises = [
  new Promise(resolve => resolve(1)),
  new Promise(resolve => resolve(2)),
  new Promise(resolve => resolve(3))
];

async function test1() {
  for await (const obj of promises) {
    console.log(obj);
  }
}

test1(); // 1, 2, 3

Так как он использует await, ты можешь использовать его только внутри async функций, как обычный await в async/await.

Promise.prototype.finally()

Когда промис выполнен успешно, он вызывает методы then() один за другим. Если что-то не получается во время этого, методы then() пропускаются и выполняется метод catch().

finally() позволяет запускать любой код, независимо от успешного или неуспешного выполнения промиса:

fetch("https://api.github.com/users/oleksiimyzgin")
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(error => console.error(error))
  .finally(() => console.log("finished"));

Улучшения регулярных выражений

Утверждения регулярных выражений lookbehind

Так выглядит lookahead (опережающая проверка) ?= (знак вопроса, равно): при опережающей проверке определяется строка, за которой следует определенная подстрока. Lookahead «смотрит» вперед и соответственно ставится в конце регулярного выражения. В данном примере мы ищем строку ‘Script’, перед которой стоит ‘Java’.

/Java(?=Script)/

/Java(?=Script)/.test('Java Script is cool'); // false - стоит пробел
/Java(?=Script)/.test('JavaScript is cool'); // true

?! выполняет обратную операцию, проверяя, если за строкой не следует определенная подстрока:

/Java(?!Script)/

/Java(?!Script)/.test('Java Script is cool'); // true - стоит пробел
/Java(?!Script)/.test('JavaScript is cool'); // false

lookbehind или ретроспективная проверка - это новая функция, которая использует ?<= (знак вопроса, знак меньше, равно) и «смотрит» назад для положительного утверждения. Так как lookbehind «смотрит» назад, то она соответственно ставится в начале регулярного выражения. В данном примере мы ищем строку ‘Java’ за которой стоит ‘Script’.

/(?<=Java)Script/

/(?<=Java)Script/.test('Java Script is cool'); // false - стоит пробел
/(?<=Java)Script/.test('JavaScript is cool'); // true

Кроме того, ты можешь использовать ?<! (знак вопроса, знак меньше, восклицательный знак), чтобы найти отрицательное утверждение.

/(?<!Java)Script/

/(?<!Java)Script/.test('Java Script is cool'); // true - стоит пробел
/(?<!Java)Script/.test('JavaScript is cool'); // false

Управляющая последовательность Unicode в \p{…} и \P{…}

В шаблоне регулярного выражения ты можешь использовать: \d для сопоставления с любой цифрой, \s для сопоставления с любым символом, который не является пробелом, \w для сопоставления с любым цифробуквенным символом включая нижнее подчеркивание т.д.

Новый функционал расширил концепцию всех символов Юникода, представив \p{} и отрицательный \P{}.

Любой символ Юникода имеет набор свойств. Например, Script определяет семейство языков; ASCII - это логическое значение, которое true для символов ASCII, и так далее. Ты можешь поместить это свойство в фигурные скобки, и регулярное выражение проверит, верно ли это:

/^\p{ASCII}+$/u.test('abc')   // ✅
/^\p{ASCII}+$/u.test('ABC@')  // ✅
/^\p{ASCII}+$/u.test('ABC🙃') // ❌

ASCII_Hex_Digit - другое логическое свойство, которое проверяет, содержит ли строка только допустимые шестнадцатеричные числа:

/^\p{ASCII_Hex_Digit}+$/u.test('0123456789ABCDEF') // ✅
/^\p{ASCII_Hex_Digit}+$/u.test('h')                // ❌

Есть много других логических свойств, которые ты просто проверяешь добавляя их имя в фигурные скобки, включая Uppercase, Lowercase, White_Space, Alphabetic, Emoji и другие:

/^\p{Lowercase}$/u.test('h') // ✅
/^\p{Uppercase}$/u.test('H') // ✅

/^\p{Emoji}+$/u.test('H')    // ❌
/^\p{Emoji}+$/u.test('🙃🙃') // ✅

В дополнение к этим двоичным свойствам, ты можешь проверить соответствует ли любое из свойств символа Юникода, определенному значению. В этом примере я проверяю, написана ли строка на греческом или латинском алфавите:

/^\p{Script=Greek}+$/u.test('ελληνικά') //✅
/^\p{Script=Latin}+$/u.test('hey')      //✅

Узнай больше обо всех свойствах, которые ты можешь использовать непосредственно в предложении.

Захват именованных групп в регулярных выражениях

В ES2018, захвату именованных групп может быть назначено имя, а не просто слот в массиве результатов:

// ДО
const re1 = /(\d{4})-(\d{2})-(\d{2})/;
const result1 = re1.exec("2019-04-10");
console.log(result1);
// ["2019-04-10", "2019", "04", "10", index: 0, input: "2019-04-10", groups: undefined]

// ПОСЛЕ (ECMAScript ES2018)
const re2 = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const result2 = re2.exec("2019-04-10");
console.log(result2);
// [ "2019-04-10", "2019", "04", "10", index: 0, input: "2019-04-10",
//    groups: {year: "2019", month: "04", day: "10"} 👈🏻👈🏻👈🏻
// ]

// result2.groups.year === '2019';
// result2.groups.month === '04';
// result2.groups.day === '10';

Флаг s для регулярных выражений

Флаг s, сокращенный от single line, заставляет . соответствовать также символам новой строки. Без этого точка соответствует обычному символу, но не новой строке:

const re3 = /hi.welcome/;
const re4 = /hi.welcome/s;

re3.test("hi\nwelcome"); // false
re4.test("hi\nwelcome"); // true

re4.dotAll; // true
re4.flags; // "s"

Website, name & logo
Copyright © 2022. Alex Myzgin