Что нового в ECMAScript 2025

5 минут чтения
Средний рейтинг статьи — 4.7

ECMAScript 2025 (ES2025) привносит множество интересных и мощных возможностей в язык JavaScript. В этом обзоре мы разберём каждое нововведение с пояснениями и примерами.

Повторяющиеся именованные группы захвата в RegExp

Ранее в регулярных выражениях нельзя было использовать одну и ту же именованную группу в разных альтернативах (через |) — это приводило к синтаксической ошибке. Начиная с ES2025, это разрешено:

const pattern = /ECMAScript(?<version>[0-9]{4})|ES(?<version>[0-9]{2})/;
 
// До ES2025:
"ECMAScript2025".match(pattern);
// SyntaxError: Duplicate capture group name
 
// После ES2025:
"ECMAScript2025".match(pattern).groups.version;
// '2025'

Новые методы для Set

ES2025 расширяет функциональность Set, добавляя методы из теории множеств:

const setOne = new Set([1, 2, 3]);
const setTwo = new Set([3, 4, 5]);
 
setOne.intersection(setTwo);         // Set { 3 }
setOne.union(setTwo);                // Set { 1, 2, 3, 4, 5 }
setOne.difference(setTwo);           // Set { 1, 2 }
setOne.symmetricDifference(setTwo); // Set { 1, 2, 4, 5 }
 
setOne.isSubsetOf(setTwo);           // false
setOne.isSupersetOf(setTwo);         // false
setOne.isDisjointFrom(setTwo);       // false

Это делает работу с множествами более декларативной и читаемой.

Subexpression Modifiers в регулярных выражениях

Теперь можно применять флаги регулярных выражений только к подвыражению:

const pattern = /^(?i:bearer) abc$/;
 
pattern.test("bearer abc"); // true
pattern.test("Bearer abc"); // true
pattern.test("bearer ABC"); // false

Флаг i применяется только к "bearer", а не ко всему выражению. Очень полезно!

Аттрибуты импорта и JSON-модули

Теперь можно явно указывать тип импортируемого модуля:

// Статический импорт
import data from "./data.json" with { type: "json" };
 
// Динамический импорт
const data = await import("./data.json", { with: { type: "json" } });
 
// Реэкспорт
export { data } from "./data.json" with { type: "json" };

Это обеспечивает корректную обработку, безопасность и поддержку будущих типов.

Хелперы итераторов

Новый API, вдохновлённый Rust, облегчает работу с итераторами:

const iter = Iterator.from("ECMAScript2025");
const numeric = iter.filter((char) => /\d/.test(char));
 
numeric.next(); // { value: '2', done: false }

Другие доступные методы:

  • map()

  • filter()

  • take()

  • drop()

  • flatMap()

  • reduce()

  • toArray()

  • forEach()

  • some()

  • every()

  • find()

Пример с drop и take:

const iter = Iterator.from("ECMAScript2025");
const lastDigits = iter.drop(10).take(4);
 
[...lastDigits]; // ["2", "0", "2", "5"]

Многие методы перекочевали из Array.prototype, их функционал должен быть вам хорошо знаком. Например, filter:

const iter = [..."ECMAScript2025"].values();
const iterNumeric = iter.filter((c) => /^\d$/.test(c));
 
iterNumeric.next();
// { value: '2', done: false }
iterNumeric.next();
// { value: '0', done: false }
iterNumeric.next();
// { value: '2', done: false }
iterNumeric.next();
// { value: '5', done: false }
iterNumeric.next();
// { value: undefined, done: true }

Promise.try()

Новая функция Promise.try() позволяет безопасно оборачивать синхронные и асинхронные операции:

const handleAction = (action) =>
  Promise.try(action)
    .then((result) => console.log(result))
    .catch((error) => console.error(error))
    .finally(() => console.log("выполнено"));
 
handleAction(() => "Смотри, мам! Без промисов!");
// Смотри, мам! Без промисов!
// выполнено
 
handleAction(() => { throw "Смотри, мам! Не промис, а ошибка!" });
// Смотри, мам! Не промис, а ошибка!
// выполнено

Без Promise.try() мы бы получили TypeError: action.then is not a function.

Float16Array

Добавлен тип Float16Array — массив 16-битных чисел с плавающей точкой. Это полезно для графики и ограниченных по памяти сред, таких как WebGL или микроконтроллеры.

RegExp.escape()

Теперь можно экранировать строки перед вставкой в регулярные выражения. Взглянем на проблему, которую решает RegExp.escape():

const sentence = "He has two dogs. I have one dog.";
const pattern = /dog./;
const newSentence = sentence.replace(pattern, "cat.");
 
console.log(newSentence);
// He has two cat.. I have one dog.

Токен . в нашем паттерне мэтчит любой символ, хотя мы хотели поймать литерал . с помощью нашего регулярного выражения. Тут-то нам и поможет RegExp.escape():

const sentence = "He has two dogs. I have one dog.";
const pattern = new RegExp(RegExp.escape("dog.")); // 👈👈👈
const newSentence = sentence.replace(pattern, "cat.");
 
console.log(newSentence);
// He has two dogs. I have one cat.

Это упрощает защиту от ошибок и уязвимостей при использовании пользовательского ввода.

Заключение

ES2025 делает JavaScript ещё мощнее, удобнее и ближе к современным языкам. Особенно радуют улучшения в регулярных выражениях, итераторах и работе с Promise. Эти фичи уже доступны в некоторых движках, и скоро станут стандартом для всех.

Следите за поддержкой в Node.js и браузерах — и пробуйте прямо сейчас с помощью Babel или флагов в V8!

5 минут чтения
Средний рейтинг статьи — 4.7

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний