
Приготовьтесь удивляться: к 2026 году JavaScript окончательно перестал быть тем языком, где для группировки массива приходилось городить «простыню» из reduce, а любая работа с датами требовала скачивания мегабайтных библиотек. Сразу несколько долгожданных предложений TC39 достигли стадии Stage 4, а браузеры и Node.js внедрили их с рекордной скоростью. В этой статье мы разберём десять наиболее значимых нововведений, опираясь на официальную документацию, репозитории TC39 и данные о поддержке, — каждое из которых радикально упрощает повседневный код и избавляет от многолетних «костылей».
1. Temporal API — дата и время без боли
Если вы когда-либо путались в методах getMonth(), возвращающем месяц от 0 до 11, или вручную вычисляли смещение часового пояса, вы по достоинству оцените Temporal. Этот API пришёл на смену объекту Date и официально стал частью ECMAScript 2026 после того, как в марте 2026 года TC39 перевела его в Stage 4.
Temporal вводит набор immutable-типов: Temporal.Instant (конкретный момент времени), Temporal.ZonedDateTime (дата-время с часовым поясом), Temporal.PlainDate, Temporal.PlainTime и другие. Главные преимущества:
- Неизменяемость — каждый Temporal-объект иммутабелен, что исключает случайные мутации.
- Встроенная работа с часовыми поясами и календарями — больше не нужно скачивать базы IANA.
- Предсказуемая арифметика — прибавление дня к
2026-03-14никогда не даст2026-03-15T00:00:00, если вы ожидали только дату.
Уже сейчас поддержка реализована в Chrome 144+, Firefox 139+, Safari Technology Preview и TypeScript 6.0. Node.js также готовит нативную интеграцию. Вот как лаконично выглядит типичная операция:
const now = Temporal.Now.zonedDateTimeISO();
const meeting = now.add({ hours: 3 });
console.log(meeting.toString()); // "2026-05-03T18:30:00+03:00[Europe/Moscow]"2. Явное управление ресурсами — using и Symbol.dispose
Одна из самых частых причин утечек памяти и незакрытых соединений — забытый блок finally. В 2026 году эта проблема решается на уровне языка. Предложение Explicit Resource Management вводит ключевое слово using, которое гарантирует освобождение ресурса при выходе из области видимости.
Механизм опирается на well-known символ Symbol.dispose (и Symbol.asyncDispose для асинхронных операций). Любой объект, реализующий метод [Symbol.dispose](), может быть использован с using. Браузеры и Node.js уже предоставляют такие объекты «из коробки» для файловых дескрипторов, сетевых соединений и блокировок.
function readConfig(path) {
using file = fs.openSync(path, 'r'); // автоматически закроется
const data = file.read();
return JSON.parse(data);
} // здесь file.dispose() вызывается неявноДля сложных сценариев есть DisposableStack — контейнер, который агрегирует несколько ресурсов и освобождает их в обратном порядке. Это особенно полезно при работе с транзакциями или многокомпонентными системами.
3. Iterator Helpers — ленивые цепочки без промежуточных массивов
Долгое время разработчики вынуждены были выбирать: либо писать компактные цепочки .map().filter().slice(), плодя промежуточные массивы, либо использовать громоздкие циклы для экономии памяти. Iterator Helpers, вошедшие в ES2025 и полностью стабилизировавшиеся к 2026 году, снимают эту дилемму.
Теперь итераторы имеют собственные методы map, filter, take, drop, flatMap и reduce, которые работают лениво — каждый элемент проходит всю цепочку прежде, чем запрашивается следующий. Никаких скрытых аллокаций.
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const firstTenEven = fibonacci()
.filter(n => n % 2 === 0)
.take(10)
.toArray();
console.log(firstTenEven); // [0, 2, 8, 34, ...] — без создания гигантского массиваПоддержка реализована во всех современных браузерах и Node.js 22+. Отслеживать статус можно на webstatus.dev.
4. Set-методы — объединение, пересечение, разность
До 2025 года для операций над множествами приходилось писать самодельные хелперы или импортировать lodash. Теперь прототип Set содержит полноценные методы теории множеств: union, intersection, difference, symmetricDifference, а также проверки isSubsetOf, isSupersetOf и isDisjointFrom.
const frontend = new Set(['HTML', 'CSS', 'JavaScript']);
const backend = new Set(['Python', 'JavaScript', 'SQL']);
const fullstack = frontend.union(backend);
// Set { 'HTML', 'CSS', 'JavaScript', 'Python', 'SQL' }
const common = frontend.intersection(backend);
// Set { 'JavaScript' }Эти методы работают на любых итерируемых объектах и уже доступны во всех современных браузерах — от Chrome 122 до Safari 17.
5. Object.groupBy() и Map.groupBy() — группировка в одну строку
Классический паттерн группировки массива через reduce всегда был многословным и подвержен ошибкам. С появлением статических методов Object.groupBy и Map.groupBy (ES2024, но широко применимы в 2026) код сокращается радикально.
const orders = [
{ id: 1, status: 'delivered' },
{ id: 2, status: 'pending' },
{ id: 3, status: 'delivered' },
];
// Было
const grouped = orders.reduce((acc, o) => {
(acc[o.status] ||= []).push(o);
return acc;
}, {});
// Стало
const grouped = Object.groupBy(orders, o => o.status);Map.groupBy удобен, когда ключами выступают не только строки, а, например, объекты или числа. Поддержка — Chrome 117+, Firefox 119+, Safari 17.4+, Node.js 21+.
6. Promise.try() — унификация синхронных и асинхронных ошибок
Сколько раз вы ловили «UnhandledPromiseRejection» из-за того, что функция иногда возвращала промис, а иногда — обычное значение? Promise.try решает эту проблему, оборачивая результат вызова в промис и корректно перехватывая как синхронные исключения, так и асинхронные ошибки.
function maybeAsync(id) {
if (id > 0) return fetch(`/api/user/${id}`);
throw new Error('Invalid id');
}
Promise.try(() => maybeAsync(-1))
.catch(err => console.error(err.message)); // "Invalid id"В отличие от Promise.resolve(fn()), метод Promise.try выполняет переданную функцию немедленно (а не планирует микротаск), что делает его идеальным для старта промис-цепочек. Поддержка: Chrome 128+, Firefox 134+, Safari 18.2+, Node.js 22.7+.
7. RegExp.escape() — безопасное экранирование спецсимволов
Каждый раз, когда требовалось вставить пользовательскую строку в регулярное выражение, приходилось вспоминать список из 14+ спецсимволов и писать функцию escapeRegExp. В ES2026 появился встроенный метод RegExp.escape(), который делает это автоматически.
const userQuery = 'price: $10.00 (sale)';
const pattern = new RegExp(`^${RegExp.escape(userQuery)}`);
// pattern: /^price:\ \$10\.00\ \(sale\)/Метод экранирует все символы, имеющие специальное значение в регулярных выражениях, предотвращая как случайные ошибки, так и возможные ReDoS-атаки. Доступен в Chrome 132+, Firefox 138+, Safari 18.4+.
8. Array.fromAsync() — асинхронные итераторы в массивы
Работа с потоками данных (стримами, генераторами, async iterables) долгое время требовала ручного сбора элементов в массив через for await...of. Метод Array.fromAsync превращает любой асинхронный итератор в обычный массив одной строкой.
async function* fetchPages(urls) {
for (const url of urls) {
yield fetch(url).then(r => r.json());
}
}
const results = await Array.fromAsync(fetchPages(['/api/1', '/api/2']));Метод обрабатывает как ReadableStream, так и пользовательские асинхронные генераторы. На декабрь 2025 года поддержка реализована в Chromium 128+ и Node.js 22+, Firefox и Safari ожидаются к середине 2026.
9. Error.isError() — надёжная проверка ошибок
Оператор instanceof Error ломается, если объект ошибки пришёл из другого realm (iframe, воркер, расширение браузера). Статический метод Error.isError() использует внутренний слот [[ErrorData]] и работает безотказно в любых контекстах.
try {
// код, потенциально выбрасывающий ошибку из воркера
} catch (e) {
if (Error.isError(e)) {
console.error('Настоящая ошибка:', e.message);
}
}Метод уже доступен во всех основных браузерах с начала 2026 года и полностью решает проблему, которая годами вызывала трудноуловимые баги в production-коде.
10. Math.sumPrecise() и нативные Base64/Hex — точная математика и бинарные данные
Замыкает наш список дуэт, который закрывает ещё два традиционно «больных» места JavaScript.
Math.sumPrecise() использует алгоритм компенсационного суммирования (схожий с алгоритмом Кэхэна), что позволяет избежать накопления ошибок плавающей точки при сложении большого количества чисел. Для финансовых расчётов и научных приложений это критически важно.
const values = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0];
console.log(Math.sumPrecise(values)); // 5.5 — точно
// Обычный reduce может дать 5.500000000000001Uint8Array.prototype.toBase64() и Uint8Array.fromBase64() добавляют нативную поддержку кодирования/декодирования Base64-строк прямо в типизированные массивы. Больше не нужно тащить для этого Buffer (Node.js) или btoa/atob с ручным преобразованием.
const bytes = new Uint8Array([72, 101, 108, 108, 111]);
const encoded = bytes.toBase64(); // "SGVsbG8="
const decoded = Uint8Array.fromBase64(encoded); // Uint8Array [72, 101, 108, 108, 111]Оба нововведения стали Baseline Newly Available к апрелю 2026 года и доступны в Chrome, Firefox, Safari и Node.js 23+.
Заключение
2026 год действительно стал переломным для JavaScript. Язык получил не просто «ещё пару методов», а полноценные инфраструктурные улучшения, которые годами ждали разработчики. Temporal API, явное управление ресурсами, ленивые итераторы, теоретико-множественные операции — все эти фичи объединяет одно: они убирают шаблонный код, уменьшают количество ошибок и делают намерения разработчика более явными. Если вы ещё не используете их в production — самое время обновить browserlist и начать писать чище, короче и надёжнее.
Error.isError(). В статье он указан как широкодоступный. Несмотря на то, что некоторые источники действительно упоминали его продвижение к Stage 4, текущие данные указывают на его нахождение на стадии Stage 2.7. Это не отменяет его полезности, но означает, что спецификация еще дорабатывается.