Обзор возможностей ES2022: Top-Level Await, .at() и не только
Введение
Благодаря ежегодному циклу релизов комитета TC39 язык JavaScript продолжает развиваться каждый год. ECMAScript 2022 (ES2022) принёс ряд новых возможностей, призванных улучшить опыт разработчиков и читаемость кода. Рассмотрим самые яркие из них.
1. await на верхнем уровне
Это одна из самых ожидаемых возможностей ES2022. Раньше ключевое слово await можно было использовать только внутри функции async. Из-за этого асинхронные операции в области видимости верхнего уровня модуля было неудобно обрабатывать: обычно асинхронный код приходилось оборачивать в IIFE (немедленно вызываемое функциональное выражение).
Раньше 👎:
// data.js
import { fetchData } from './api.js';
let data;
(async () => {
data = await fetchData();
// ... 只能在这里使用 data
})();
export { data }; // 导出时 data 还是 undefinedТеперь (ES2022) 👍:
// data.js
import { fetchData } from './api.js';
const data = await fetchData();
export { data }; // 模块会等待 await 完成后再被其他模块评估Top-level await значительно упрощает динамическую загрузку модулей, инициализацию зависимостей и другие подобные сценарии, делая асинхронный код более интуитивным.
2. Метод индексирования массивов и строк .at()
Чтобы получить последний элемент массива в JavaScript, обычно приходится писать arr[arr.length - 1], что многословно и чревато ошибками. ES2022 вводит метод .at(), унифицирующий работу с прямыми и обратными индексами.
Метод .at() принимает целое число. Положительное число возвращает элемент с соответствующим индексом, а отрицательное отсчитывает элементы с конца.
Раньше 👎:
const arr = [1, 2, 3, 4, 5];
const lastElement = arr[arr.length - 1]; // 5
const secondToLast = arr[arr.length - 2]; // 4Теперь (ES2022) 👍:
const arr = [1, 2, 3, 4, 5];
const lastElement = arr.at(-1); // 5
const secondToLast = arr.at(-2); // 4
// 同样适用于字符串
const str = 'hello';
console.log(str.at(-1)); // 'o'3. Object.hasOwn(obj, prop)
Чтобы проверить, есть ли у объекта собственное, а не унаследованное свойство, обычно используют Object.prototype.hasOwnProperty.call(obj, prop). Такая запись очень громоздка и в некоторых случаях, например с объектами, созданными через Object.create(null), может привести к ошибке.
Object.hasOwn() предлагает более короткий и надёжный статический метод.
Раньше 👎:
const obj = { a: 1 };
console.log(Object.prototype.hasOwnProperty.call(obj, 'a')); // true
console.log(Object.prototype.hasOwnProperty.call(obj, 'toString')); // falseТеперь (ES2022) 👍:
const obj = { a: 1 };
console.log(Object.hasOwn(obj, 'a')); // true
console.log(Object.hasOwn(obj, 'toString')); // false4. Другие примечательные возможности
- Error Cause: Конструктор
Errorтеперь может принимать второй аргумент, указывающий «причину» ошибки, что облегчает создание более понятных цепочек ошибок.try { // ... } catch (err) { throw new Error('New error message', { cause: err }); } - Индексы совпадений RegExp (флаг
/d): При использовании флага/dрезультат регулярного выражения дополнительно содержит начальный и конечный индексы каждой группы захвата.
Заключение
Хотя новые возможности ES2022 не принесли революционных изменений, они дорабатывают JavaScript в деталях, решают многие давние проблемы разработчиков и делают код более кратким и надёжным.