JavaScript в 2025 году: что нового?
2025 год стал знаковым для экосистемы JavaScript. Язык, который начинался как простой скриптовый инструмент для браузеров, теперь уверенно доминирует в веб-разработке, серверной части (Node.js) и даже в настольных приложениях. В этом году вышли долгожданные спецификации ECMAScript 2025, а экосистема Node.js получила ряд критически важных улучшений. В этой статье мы разберем ключевые новинки, которые должен знать каждый разработчик.
1. Temporal API: новая эра работы с датами и временем
Одна из самых больших головных болей в JavaScript — работа с датами через устаревший объект Date. В 2025 году эта проблема наконец решена. Temporal API — это современный, иммутабельный и типобезопасный способ работы с датами, временем, часовыми поясами и календарями.
Temporal предоставляет несколько типов объектов:
Temporal.Instant— точный момент времени (наносекундная точность).Temporal.PlainDate— дата без времени (например, 2025-03-15).Temporal.PlainTime— время без даты.Temporal.ZonedDateTime— дата и время с часовым поясом.
Пример: работа с часовыми поясами в Node.js
import { Temporal } from '@js-temporal/polyfill';
// Текущее время в UTC
const now = Temporal.Now.instant();
console.log('Сейчас (UTC):', now.toString());
// Конвертация в часовой пояс Москвы
const moscowTime = now.toZonedDateTimeISO('Europe/Moscow');
console.log('Время в Москве:', moscowTime.toString());
// Сложение 2 часов
const later = now.add({ hours: 2 });
console.log('Через 2 часа:', later.toZonedDateTimeISO('Europe/Moscow').toString());
// Сравнение дат
const deadline = Temporal.PlainDate.from('2025-12-31');
const today = Temporal.Now.plainDateISO();
const daysLeft = today.until(deadline).days;
console.log(`До дедлайна осталось: ${daysLeft} дней`);
2. Декораторы: стандартизация и практическое применение
После долгих лет экспериментов и предложений, декораторы наконец вошли в стандарт ECMAScript 2025. В отличие от экспериментальной версии TypeScript, новый синтаксис декораторов более гибкий и безопасный. Декораторы позволяют легко добавлять метаданные, логирование, валидацию или мемоизацию к классам и их методам.
Пример: декоратор для логирования выполнения функции в Node.js
function logExecution(target, context) {
const methodName = String(context.name);
const originalMethod = target;
return function (...args) {
console.log(`[LOG] Вызов метода: ${methodName}, аргументы:`, args);
const start = performance.now();
const result = originalMethod.apply(this, args);
const end = performance.now();
console.log(`[LOG] Метод ${methodName} выполнен за ${(end - start).toFixed(2)} мс`);
return result;
};
}
class DataProcessor {
@logExecution
processData(data) {
// Симуляция тяжелой работы
let sum = 0;
for (let i = 0; i < 1e6; i++) {
sum += data[i % data.length];
}
return sum;
}
}
const processor = new DataProcessor();
const result = processor.processData([1, 2, 3, 4, 5]);
console.log('Результат:', result);
3. Параллельная обработка данных: Worker Threads 2.0
Node.js в 2025 году получил значительное обновление модуля worker_threads. Теперь он поддерживает SharedArrayBuffer с атомарными операциями и улучшенное управление памятью. Это позволяет эффективно обрабатывать большие объемы данных без блокировки основного цикла событий.
Ключевые улучшения:
- Поддержка
Atomics.waitAsyncдля неблокирующего ожидания. - Улучшенная передача сложных объектов через
postMessage. - Новый API
poolдля создания пулов воркеров.
Пример: параллельный парсинг большого JSON-файла
import { Worker } from 'node:worker_threads';
import { cpus } from 'node:os';
function createWorker(data, workerData) {
return new Promise((resolve, reject) => {
const worker = new Worker('./parser-worker.js', { workerData });
worker.on('message', resolve);
worker.on('error', reject);
});
}
async function main() {
const largeDataset = Array.from({ length: 100000 }, (_, i) => ({ id: i, value: Math.random() * 1000 }));
const numWorkers = cpus().length;
const chunkSize = Math.ceil(largeDataset.length / numWorkers);
const promises = [];
for (let i = 0; i < numWorkers; i++) {
const chunk = largeDataset.slice(i * chunkSize, (i + 1) * chunkSize);
promises.push(createWorker(chunk, { workerId: i }));
}
const results = await Promise.all(promises);
const totalSum = results.reduce((acc, val) => acc + val, 0);
console.log(`Общая сумма: ${totalSum}`);
}
main().catch(console.error);
Файл parser-worker.js:
import { parentPort, workerData } from 'node:worker_threads';
const { data, workerId } = workerData;
const sum = data.reduce((acc, item) => acc + item.value, 0);
console.log(`Воркер ${workerId} обработал ${data.length} записей`);
parentPort.postMessage(sum);
4. Signal API и реактивность в браузере
Хотя это напрямую не относится к Node.js, для полноты картины стоит упомянуть Signal API, который появился в браузерном JavaScript. Это встроенная система реактивности, которая позволяет создавать сигналы (реактивные переменные) и эффекты, обновляющиеся при изменении зависимостей. Это значительно упрощает разработку сложных интерфейсов без использования внешних библиотек (например, Solid.js или Preact Signals).
Пример (браузерный JavaScript):
const count = new Signal.State(0);
const doubled = new Signal.Computed(() => count.get() * 2);
// Подписка на изменения
Signal.effect(() => {
document.getElementById('output').textContent = `Значение: ${doubled.get()}`;
});
// Изменяем состояние
count.set(5); // Автоматически обновит UI
Заключение
JavaScript в 2025 году стал более зрелым и мощным языком. T