🔍

Стандарт ES2020

Стандарт ES2020

Комитет TC39 недавно одобрил что войдёт в стандарт ECMAScript 2020 (широко известную как ES2020), которая содержит завершенный набор улучшений, входящий в язык JavaScript. Стандарт ES2020 должен быть рассмотрен и утвержден Генеральной ассамблеей ECMA в июне этого года. Большинство новых улучшений уже реализованы в браузерах и могут использоваться с помощью транспайлера Babel.

Спецификация ES2020 будет содержать:

  • matchAll - метод Strings, который создаёт итератор для всех объектов соответствия, сгенерированных глобальным регулярным выражением;
  • import () - синтаксис для асинхронного импорта модулей с динамическим спецификатором;
  • BigInt - для работы с произвольными целыми числами больших, чем 25^53 - 1 ;
  • Promise.allSettled - новый комбинатор Promise, который не замыкается;
  • globalThis - универсальный способ доступа к глобальному значению this;
  • выделенный экспорт * as ns from 'module' для использования внутри модулей;
  • повышена стандартизация for-in порядка перечисления;
  • import.meta - объект, заполненный хостом, доступный в модулях, который может содержать контекстную информацию о модуле;
  • и две новые функции синтаксиса для улучшения работы с «нулевыми» значениями (null или undefined): nullish coalescing - оператор выбора значений; optional chaining - позволяет считывать значение свойства, расположенного глубоко в цепочке связанных объектов, без необходимости явно проверять правильность каждой ссылки в цепочке.

Динамический импорт

Может использоваться для динамической загрузки модулей, созданных на этапе разделения кода в отдельные бандлы. Динамический импорт поддерживается большинством браузеров, за исключением IE11. С помощью import () разработчики могут импортировать динамически созданный модуль (moduleSpecifier = dir + 'my-math.mjs') асинхронно (вернётся Promise). Можно использовать по условию в любом месте кода:

const dir = './lib/';
const moduleSpecifier = dir + 'my-math.mjs';

async function loadConstant() {
  const myMath = await import(moduleSpecifier);
  const result = myMath.LIGHTSPEED;
  assert.equal(result, 299792458);
  return result;
}

import.meta

Это объект, который содержит специфичные для хоста метаданные о текущем модуле. На сегодняшний день наиболее интересным свойством является url, то есть строка с URL-адресом текущего файла модуля. Наличие этого URL позволяет разработчикам импортировать связанные модули или условно выполнять операции в зависимости от текущего модуля. Предложение предлагает следующий пример, который выбирает файл hamster.jpg относительно текущего модуля:

(async () => {
  const response = await fetch(new URL('../hamsters.jpg', import.meta.url));
  const blob = await response.blob();

  const size = import.meta.scriptElement.dataset.size || 300;

  const image = new Image();
  image.src = URL.createObjectURL(blob);
  image.width = image.height = size;

  document.body.appendChild(image);
})();

Когда этот модуль загружен, независимо от его местоположения, он загрузит одноуровневый файл hamsters.jpg и отобразит изображение. Размер изображения можно настроить с помощью элемента script, который используется для его импорта, например: <script type = "module" src = "path/to/hamster-displayer.mjs" data-size = "500"> </ script>

globalThis

Ключевое слово globalThis позволяет разработчикам писать код ECMAScript, который обращается к глобальному объекту, избавляя от необходимости использовать window, self, global соответственно в браузере, воркере, Node.js и работая с другими средами.

export * as ns from "mod"

Новый синтаксис экспорта (export * as ns from "mod") добавляет новую форму экспорта, из которой экспортируется экзотический объект пространства имен другого модуля в качестве экспортированного имени другого, заполняя сценарий использования, аналогичный сценариям использования для существующего экспорта из форм.

Promise.allSettled()

Promise.allSettled() завершает существующие Promise.all() и Promise.race() ECMAScript ES2015 и обрабатывает случай, когда все промисы выполняются независимо от результата (выполненного или отклоненного), позволяя писать код следующим образом:

Promise
  .allSettled([
    fetch('https://api.github.com/users/pawelgrzybek').then(data => data.json()),
    fetch('https://api.github.com/users/danjordan').then(data => data.json())
  ])
  .then(result => console.log('All profile settled'));

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

Optional chaining (a? .B) и nullish coalescing (a ?? b)

Optional chaining (a? .B) и nullish coalescing (a ?? b) поддерживаются в Babel (начиная с Babel 7.0); Edge, Chrome и Firefox вечнозеленые браузеры; а также TypeScript 3.7+. Обе функции допускают замыкания, если значение для доступа / вызова равно нулю. Например, пусть x = foo?.Bar.baz(); кратко заменяет:

let x = foo === null || foo === undefined? undefined: foo.bar.baz ();

BigInt()

В то время как 2 ^ 53 + 1 ошибочно оценивается как 9007199254740992 (число нечетное, поэтому не может заканчиваться цифрой 2), следующие 2n ** 53n + 1n правильно оцениваются как 9007199254740993n. Подобные ограничения являются одной из причин того, что JSON API в Twitter возвращает идентификаторы твитов в виде строк, а не буквальных чисел. BigInt поддерживается в большинстве современных браузеров (включая Firefox 68+, Chrome 67+) и может работать в других браузерах.

String.matchAll

Поддерживается во всех вечнозеленых браузерах, за исключением Safari. Метод matchAll() возвращает итератор всех результатов, сопоставляющих строку с регулярным выражением, включая группы захвата:

const text = 'From 2019.01.29 to 2019.01.30';
const regexp = /(?<year>\d{4}).(?<month>\d{2}).(?<day>\d{2})/gu;
const results = Array.from(text.matchAll(regexp));

// results:
// [
//   [
//     '2019.01.29',
//     '2019',
//     '01',
//     '29',
//     index: 5,
//     input: 'From 2019.01.29 to 2019.01.30',
//     groups: { year: '2019', month: '01', day: '29' }
//   ],
//   [ (...) ]
// ]

TC39 - это группа разработчиков, разработчиков, разработчиков и других разработчиков JavaScript, которые сотрудничают с сообществом для поддержки и развития спецификации JavaScript (формально, ECMAScript). TC39 включает в себя всех основных поставщиков браузеров. Каждое предложение для функции ECMAScript проходит следующие стадии зрелости:

  • Этап 0: Strawman;
  • Этап 1: Предложение;
  • Этап 2: Черновик;
  • Этап 3: Кандидат;
  • Этап 4: Закончено.

Функция будет включена в стандарт, как только ее предложение достигнет стадии 4, и, таким образом, ее можно безопасно использовать.

ECMAScript 2020 - одиннадцатое издание Спецификации языка ECMAScript. Со времени публикации первого издания в 1997 году ECMAScript стал одним из наиболее широко используемых в мире языков программирования общего назначения.

Читать ещё:

Что такое Nullish Coalescing

Что такое Nullish Coalescing

Что такое event loop?

Что такое event loop?