Specyfikacja ECMAScript ewoluuje co roku, ale większość developerów dowiaduje się o nowych funkcjach przypadkiem albo z tweetów wyrwanych z kontekstu. A między "fajnie wygląda w poście" a "nadaje się do produkcji" jest jeszcze kwestia wsparcia środowiska, bundlera i realnego use case'u.
Tymczasem w ostatnich rocznikach standardu pojawiło się sporo funkcji, które rozwiązują realne, codzienne problemy. Część jest gotowa do użycia od razu, część wymaga jeszcze ostrożności albo polyfillu. Ten artykuł pokazuje jedno i drugie.
Krótka odpowiedź: Najbardziej praktyczne nowości to Object.groupBy(), toSorted()/toReversed(), Set methods i Promise.withResolvers(), ale każdą z nich warto sprawdzić pod kątem wsparcia w docelowym runtime. Temporal nadal zwykle wymaga polyfillu, a iterator helpers są świeże i bardziej zależne od środowiska niż od samej daty publikacji specyfikacji.
Oto przegląd najciekawszych nowości, które prawdopodobnie przegapiłeś. Jeśli potrzebujesz odświeżenia fundamentów, wróć najpierw do takich tematów jak scope, closures, this, prototypy i Event Loop.
1. Object.groupBy() — koniec z reduce do grupowania
Ile razy pisałeś reduce() żeby pogrupować tablicę? Nigdy więcej:
Ważny detal: Object.groupBy() zwraca obiekt z null prototype. To zwykle zaleta, ale oznacza też, że metody w stylu grouped.hasOwnProperty(...) nie zadziałają tak jak w zwykłym obiekcie.
Jest też Map.groupBy() jeśli potrzebujesz Map zamiast obiektu:
To wygodne, ale używaj świadomie. Promise.withResolvers() bardzo ułatwia tworzenie Promise "wiszących" w nieskończoność albo zostawianie listenerów bez cleanupu, jeśli zapomnisz o ścieżce błędu i anulowaniu.
3. Array.toSorted(), toReversed(), toSpliced() — immutable operations (ES2023, często pomijane)
Stare metody sort(), reverse(), splice() mutują oryginalną tablicę. To problem w React i innych miejscach gdzie immutability ma znaczenie. Więcej takich trików znajdziesz w 10 sztuczek w JavaScript.
W praktyce to jedne z najbardziej przydatnych nowości ostatnich lat, szczególnie w React, reducerach i wszędzie tam, gdzie nie chcesz przypadkiem mutować danych wejściowych.
4. Set methods — union, intersection, difference
Wreszcie! Operacje na zbiorach bez ręcznego iterowania:
Code
const a = new Set([1, 2, 3, 4])const b = new Set([3, 4, 5, 6])// Union — suma zbiorówa.union(b) // Set {1, 2, 3, 4, 5, 6}// Intersection — część wspólnaa.intersection(b) // Set {3, 4}// Difference — elementy z A, których nie ma w Ba.difference(b) // Set {1, 2}// Symmetric difference — elementy unikalne dla każdego zbiorua.symmetricDifference(b) // Set {1, 2, 5, 6}// Sprawdzanie relacjia.isSubsetOf(new Set([1, 2, 3, 4, 5])) // truea.isSupersetOf(new Set([1, 2])) // truea.isDisjointFrom(new Set([7, 8, 9])) // true
Jeśli pracujesz dużo na filtrach, uprawnieniach, tagach albo zbiorach identyfikatorów, te metody bardzo szybko zastępują własne helpery.
5. Iterator helpers — lazy evaluation
Nowe metody na iteratorach pozwalają na leniwe przetwarzanie danych:
Code
function* infiniteNumbers() { let i = 0 while (true) { yield i++ }}// Weź tylko 5 pierwszych parzystychconst result = infiniteNumbers() .filter(n => n % 2 === 0) .take(5) .toArray()console.log(result) // [0, 2, 4, 6, 8]
Ważny niuans: iterator helpers działają na iteratorach, nie bezpośrednio na tablicach. Dla tablic potrzebujesz np. Iterator.from(array) albo array.values():
Code
const result = Iterator.from([1, 2, 3, 4]) .map((n) => n * 2) .toArray()
Dostępne metody:
map(fn) — transformacja
filter(fn) — filtrowanie
take(n) — pierwsze n elementów
drop(n) — pomiń pierwsze n
flatMap(fn) — map + flatten
reduce(fn, init) — agregacja
toArray() — konwersja do tablicy
forEach(fn) — iteracja z efektem ubocznym
some(fn) / every(fn) — predykaty
find(fn) — pierwszy pasujący
Różnica vs array methods: lazy evaluation. Iterator nie przetwarza wszystkiego od razu, tylko tyle, ile potrzeba. To robi różnicę przy dużych strumieniach danych, generatorach i pipeline'ach, których nie chcesz od razu materializować do tablicy.
6. Temporal API (ES2025) — koniec z Date i moment.js
Date w JavaScript jest... problematyczny. Temporal to kompletna wymiana:
Code
// Aktualna data i czasconst now = Temporal.Now.plainDateTimeISO()// 2025-09-18T13:45:30.123456789// Tworzenie datconst date = Temporal.PlainDate.from('2025-12-25')const time = Temporal.PlainTime.from('14:30:00')const dateTime = Temporal.PlainDateTime.from('2025-12-25T14:30:00')// Strefy czasowe — wreszcie działają poprawnie!const warsaw = Temporal.ZonedDateTime.from('2025-12-25T14:30:00[Europe/Warsaw]')const tokyo = warsaw.withTimeZone('Asia/Tokyo')
To najważniejsza "jakościowa" zmiana na tej liście, ale jednocześnie taka, do której najczęściej nadal potrzebujesz polyfillu. Jeśli dziś wdrażasz Temporal, najrozsądniej robić to przez @js-temporal/polyfill, a nie zakładać pełne natywne wsparcie wszędzie.
7. RegExp v flag — Unicode sets
Nowa flaga v rozszerza możliwości regex dla Unicode:
To funkcja niszowa, ale bardzo cenna tam, gdzie zwykłe regexy robią się nieczytelne: walidacja Unicode, parsery i operacje na klasach znaków.
8. Resizable ArrayBuffer
Bufory, które mogą zmieniać rozmiar bez kopiowania:
Code
// Stary sposób — trzeba tworzyć nowy buforconst oldBuffer = new ArrayBuffer(10)const newBuffer = new ArrayBuffer(20)new Uint8Array(newBuffer).set(new Uint8Array(oldBuffer))// ✅ ES2024 — resize w miejscuconst buffer = new ArrayBuffer(10, { maxByteLength: 100 })buffer.resize(20) // Rozszerz bez kopiowaniabuffer.resize(5) // Zmniejsz
Przydatne dla WebAssembly, binary protocols, streaming data.
To nie jest nowość dla każdego frontendowca, ale jeśli pracujesz z danymi binarnymi, przeglądarkowymi codecami albo WebAssembly, zaczyna być naprawdę użyteczna.
9. JSON modules (Import Assertions → Attributes)
Import JSON jako moduł ES:
Code
// Stara składnia (deprecated)import data from './config.json' assert { type: 'json' }// ✅ Nowa składnia (ES2025)import data from './config.json' with { type: 'json' }console.log(data.apiUrl)
Tu warto uważać szczególnie na tooling. Sam standard to jedno, ale bundler, runtime i konfiguracja TypeScriptu mogą mieć własne wymagania albo inne domyślne zachowanie.
10. Float16Array — half-precision floats
Nowy typ tablicy dla 16-bitowych floatów — przydatne w machine learning:
Code
const f16 = new Float16Array([1.5, 2.5, 3.5])// Konwersjaconst f32 = new Float32Array(f16) // do 32-bitconst f16Back = new Float16Array(f32) // z powrotem// Math.f16round — zaokrąglenie do half-precisionMath.f16round(1.337) // 1.3369140625
Half-precision używa 2 bajty zamiast 4 (float32) lub 8 (float64). Oszczędność pamięci kosztem precyzji.
To funkcja mocno specjalistyczna. Jeśli nie pracujesz przy grafice, WebGPU, ML albo transmisji danych numerycznych, prawdopodobnie długo jej nie użyjesz. Ale dobrze wiedzieć, że język zaczyna pokrywać także takie scenariusze.
Albo sprawdź na caniuse.com lub node.green. Przy nowszych funkcjach standardu to ważniejsze niż sama data publikacji specyfikacji.
FAQ
Co to jest Object.groupBy() i jak go używać?
Object.groupBy(array, keyFn) grupuje elementy tablicy według klucza zwracanego przez callback. Zastępuje ręczne reduce() do grupowania: Object.groupBy(products, p => p.category) zwraca obiekt gdzie klucze to wartości kategorii, a wartości to tablice pasujących elementów. Funkcja jest już dostępna w nowoczesnych przeglądarkach i nowych wersjach Node.js, ale przed wdrożeniem nadal sprawdź compatibility table dla swojego środowiska. Zwraca obiekt z null prototype — hasOwnProperty() na nim nie zadziała. Map.groupBy() to wersja zwracająca Map.
Czym są immutable array methods (toSorted, toReversed)?
ES2023 wprowadził niemutujące odpowiedniki starych metod tablicowych: toSorted() (zamiast sort()), toReversed() (zamiast reverse()), toSpliced() (zamiast splice()), with(index, value) (zamiast bezpośredniego przypisania). Stare metody mutują oryginalną tablicę — problem w React i wszędzie gdzie immutability ma znaczenie. Nowe zwracają nową tablicę, oryginał zostaje niezmieniony. To jedna z nowości z najszerszym i najbardziej praktycznym wsparciem, ale starsze środowiska nadal wymagają sprawdzenia compatibility table.
Co to jest Promise.withResolvers()?
Promise.withResolvers() zwraca obiekt { promise, resolve, reject } — pozwala "externalizować" resolve/reject poza konstruktor Promise. Przed ES2024 wymagało to brzydkiego workaroundu z let resolve; new Promise(res => { resolve = res }). Przydatne przy event-driven code, kolejkach i mostkowaniu callbackowego API, czyli Application Programming Interface, definiuje sposób komunikacji między aplikacjami lub modułami. do Promise. Uważaj na "wiszące" Promise — jeśli zapomnisz wywołać resolve lub reject, Promise nigdy się nie rozwiąże.
Co to jest Temporal API i kiedy go używać?
Temporal to nowy standard JavaScript zastępujący problematyczny obiekt Date. Oferuje czytelne typy: Temporal.PlainDate, Temporal.PlainTime, Temporal.ZonedDateTime z poprawną obsługą stref czasowych. Operacje: date.add({ months: 2 }), date.until(other), porównywanie. W ES2025, ale wsparcie przeglądarek jest jeszcze niepełne. Do produkcji używaj @js-temporal/polyfill. Długoterminowo zastąpi moment.js, date-fns i new Date().
Jak działają nowe Set methods w JavaScript?
ES2025 dodało metody operacji na zbiorach: set.union(other) (suma), set.intersection(other) (część wspólna), set.difference(other) (elementy w A, których nie ma w B), set.symmetricDifference(other) (unikalne dla każdego zbioru). Plus sprawdzanie relacji: isSubsetOf(), isSupersetOf(), isDisjointFrom(). Eliminują konieczność ręcznego iterowania przez dwa zbiory. Przydatne przy filtrach, uprawnieniach i tagach. W najnowszych silnikach są już dostępne, ale w starszych środowiskach wciąż mogą wymagać fallbacku.
Co to są Iterator helpers i czym różnią się od metod tablicowych?
Iterator helpers (filter, map, take, drop, flatMap, reduce, toArray) działają na iteratorach, nie na tablicach. Kluczowa różnica: lazy evaluation — operacje są wykonywane tylko dla tylu elementów, ile potrzebujesz, a nie dla całej kolekcji naraz. Idealne dla generatorów, nieskończonych sekwencji i dużych zbiorów danych. Dla tablic potrzebujesz Iterator.from(array). To jedna z bardziej świeżych nowości, więc przed wdrożeniem do produkcji szczególnie warto sprawdzić wsparcie w runtime i testach CI.
Jak sprawdzić czy nowa funkcja JavaScript jest gotowa do użycia?
Feature detection w kodzie: if (typeof Object.groupBy === 'function') { ... }. Zewnętrzne narzędzia: caniuse.com (wsparcie przeglądarek), node.green (wsparcie Node.js), MDN Web Docs (dokumentacja + compatibility table). Przy budowaniu na polyfillach: sprawdź czy Babel/TypeScript poprawnie transpiluje. Ważna zasada: data publikacji specyfikacji ≠ dostępność w przeglądarkach — może minąć rok lub więcej.
ES2024/2025 przynosi funkcje, które eliminują potrzebę wielu utility libraries:
Problem
Stare rozwiązanie
ES2024/2025
Grupowanie
lodash.groupBy
Object.groupBy
Operacje na zbiorach
ręczne iterowanie
Set methods
Immutable array ops
[...arr].sort()
toSorted(), toReversed()
Daty i strefy czasowe
moment.js, date-fns
Temporal API
Promise externalization
workaroundy
Promise.withResolvers
Lazy iteration
własna implementacja
Iterator helpers
JavaScript staje się coraz bardziej kompletnym językiem, ale nie każda nowość od razu nadaje się do produkcji w każdym projekcie. Najlepsze podejście to traktować te funkcje jak nowe narzędzia w skrzynce: sprawdzić wsparcie, zrozumieć trade-offy i wdrażać tam, gdzie faktycznie upraszczają kod. A jeśli chcesz optymalnie korzystać z Promise, przeczytaj też o pułapkach async/await i mocy Promise.all.
Chcesz pisać czystszy kod? Sprawdź 10 sztuczek w JavaScript albo dołóż do tego solidne zrozumienie scope, closures i asynchroniczności.
Pracuję z tym zawodowo.
Jeśli chcesz przełożyć ten temat na lepszą architekturę frontendu, uporządkować React lub Next.js i podnieść jakość pracy zespołu, skontaktuj się ze mną. Pomagam zamieniać wiedzę z artykułów w praktyczne decyzje technologiczne.
Maciej Sala — project manager i frontendowiec z doświadczeniem w marketingu internetowym. Na co dzień pracuję z Reactem, Next.js i TypeScriptem, łącząc perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat związany z branżą gier wideo jako project manager i game designer.
Absolwent historii na Uniwersytecie Jagiellońskim i studiów podyplomowych z marketingu internetowego na Akademii Górniczo-Hutniczej w Krakowie. Poza pracą trenuje na siłowni, maluje figurki i realizuje własne projekty.
Astro.js vs Next.js — które narzędzie wybrać w 2026 roku?
Fachowe porównanie Astro.js i Next.js z perspektywy developera pracującego na co dzień w Next.js. Architektura, wydajność, SEO, DX, koszty i konkretne use case — z benchmarkami i przykładami kodu.
WordPress → Next.js — migracja treści, redirecty 301 i zachowanie pozycji SEO
Jak przenieść stronę z WordPress na Next.js bez utraty pozycji w Google? Eksport treści, mapowanie URL, redirecty 301, migracja obrazów i weryfikacja indeksacji.
Google Search Console + Next.js — indeksacja, błędy, performance i co z nimi robić
Jak korzystać z Google Search Console dla strony Next.js? Weryfikacja, sitemap, indeksacja, Core Web Vitals, crawl budget i najczęstsze problemy — praktyczny poradnik.