Комитет 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 стал одним из наиболее широко используемых в мире языков программирования общего назначения.