JS
() =>
JavaScript · ES2024 · ES2025 · ECMAScript · Neue Features
ES2024 & ES2025: alle neuen JavaScript-Features
von Object.groupBy bis zur Temporal API

ECMAScript entwickelt sich schneller als je zuvor. ES2024 und ES2025 bringen Features, die seit Jahren in der Community gefordert wurden: Gruppierung von Daten, bessere Promise-Kontrolle, echte Datumsverarbeitung ohne Bibliotheken und strukturiertes Pattern Matching. Dieser Artikel deckt jeden wichtigen Zusatz mit konkreten Beispielen ab.

18 Min. Lesezeit Object.groupBy · Temporal · Iterator Helpers · Dekoratoren Chrome 117+ · Node.js 21+ · Stage-3-Proposals

1. Der TC39-Prozess: wie Features in JavaScript kommen

ECMAScript-Features durchlaufen einen standardisierten fünfstufigen Prozess beim TC39-Komitee. ES2024-Features und ES2025-Features haben Stage 4 erreicht – die höchste Stufe, die bedeutet: mindestens zwei unabhängige Implementierungen existieren, der Test262-Testsuite-Eintrag ist vollständig, und das Komitee hat die Aufnahme in die Spezifikation abgestimmt. Features in Stage 3 sind "kandidatenreif" und werden von Browser-Engines bereits implementiert, können aber noch Änderungen erfahren. Stage-2-Features haben ein ausgearbeitetes Design, aber noch keine vollständige Spezifikation.

Dieser Kontext ist wichtig, um die ES2024- und ES2025-Features einzuordnen. Wer die neuen Sprachfeatures in Production nutzen will, muss Browser-Kompatibilität, Transpilier-Support (Babel, TypeScript) und Polyfill-Verfügbarkeit kennen. Die meisten ES2024-Features sind in Chrome 117+, Firefox 117+ und Safari 17+ verfügbar. Node.js 21 implementiert einen Großteil ohne Flag. TypeScript 5.3+ unterstützt die wichtigsten neuen Syntax-Features. Beim Einsatz ohne Transpiler ist caniuse.com die zuverlässigste Quelle für den aktuellen Stand.

2. Object.groupBy und Map.groupBy (ES2024)

Object.groupBy() ist eines der meisterwarteten ES2024-Features. Es nimmt ein iterierbares Objekt und eine Callback-Funktion, die für jedes Element einen Schlüssel zurückgibt, und gruppiert alle Elemente in ein Objekt, dessen Keys die Gruppenschlüssel sind. Das löst ein alltägliches Problem, das bisher mit Array.prototype.reduce() und einer akkumulierenden Hilfsvariable gelöst wurde – umständlich, schwer lesbar, fehleranfällig. Object.groupBy macht das zur einzeiligen, semantisch klaren Operation.

Map.groupBy() funktioniert identisch, gibt aber eine Map zurück statt eines plain Objects. Der entscheidende Unterschied: Als Schlüssel können beliebige Werte verwendet werden, nicht nur Strings. Das ist unverzichtbar, wenn man nach Objekten, Dates oder anderen nicht-primitiven Werten gruppieren will. Beide Methoden sind nicht-destruktiv – sie verändern das ursprüngliche Iterable nicht. Das Ergebnis-Objekt hat kein Prototyp (Object.create(null) intern), was bedeutet: Keine Prototype-Pollution-Probleme und keine versehentliche Überschreibung von Properties wie constructor oder toString.


// ES2024: Object.groupBy — replaces complex reduce() patterns
const orders = [
  { id: 1, status: 'pending', amount: 99 },
  { id: 2, status: 'shipped', amount: 249 },
  { id: 3, status: 'pending', amount: 35 },
  { id: 4, status: 'delivered', amount: 180 },
  { id: 5, status: 'shipped', amount: 75 },
];

// Group by status — clean, readable, no reduce() boilerplate
const byStatus = Object.groupBy(orders, order => order.status);
// { pending: [{id:1,...},{id:3,...}], shipped: [{id:2,...},{id:5,...}], delivered: [...] }

// Map.groupBy: use objects or Dates as keys
const products = [
  { name: 'Laptop', category: { id: 1, name: 'Electronics' }, price: 999 },
  { name: 'Phone', category: { id: 1, name: 'Electronics' }, price: 699 },
  { name: 'Desk', category: { id: 2, name: 'Furniture' }, price: 399 },
];

const categories = [...new Set(products.map(p => p.category))];
const byCategory = Map.groupBy(products, p => p.category);
// Map keys are the actual category objects, not stringified versions

// Price range grouping — replaces multiple filter() chains
const byPriceRange = Object.groupBy(products, ({ price }) => {
  if (price < 400) return 'budget';
  if (price < 800) return 'mid-range';
  return 'premium';
});

3. Promise.withResolvers und Promise-Verbesserungen (ES2024)

Promise.withResolvers() ist ein weiteres praktisches ES2024-Feature, das ein häufiges Boilerplate-Pattern eliminiert. Bisher musste man, um auf resolve und reject außerhalb des Promise-Konstruktors zugreifen zu können, eine umständliche Konstruktion nutzen: Die Callbacks in äußere Variablen extrahieren, indem man den Konstruktor mit einer Funktion aufruft, die diese Variablen setzt. Das "Deferred"-Pattern ist in vielen Bibliotheken implementiert, aber nicht Teil der Sprache. Promise.withResolvers() gibt ein Objekt mit drei Properties zurück: promise, resolve und reject.

Besonders nützlich ist dieses ES2024-Feature bei der Implementierung von Event-Queues, beim Warten auf externe Events in async-Kontexten oder beim Erstellen von Test-Utilities, die auf asynchrone Callbacks warten müssen. Ein konkretes Beispiel: Ein WebSocket-Client, der auf die erste "open"-Nachricht warten soll, kann mit Promise.withResolvers() ein Promise erstellen, dessen resolve-Funktion direkt als Event-Listener registriert wird – ohne die Umweg-Konstruktion mit äußeren Variablen. Das macht den Code kompakter und seinen Intent klarer.


// ES2024: Promise.withResolvers — the Deferred pattern, standardized
const { promise, resolve, reject } = Promise.withResolvers();

// Pass resolve directly as an event callback — no wrapper needed
document.addEventListener('DOMContentLoaded', resolve, { once: true });
await promise; // resolves when DOM is ready

// WebSocket readiness — clean pattern without outer variable hoisting
async function connectWebSocket(url) {
  const ws = new WebSocket(url);
  const { promise: ready, resolve: onOpen, reject: onError } = Promise.withResolvers();

  ws.addEventListener('open', onOpen, { once: true });
  ws.addEventListener('error', onError, { once: true });

  await ready; // throws if 'error' fires first
  return ws;
}

// Timeout race — combine with AbortController
async function fetchWithTimeout(url, ms) {
  const { promise: timeout, reject: abort } = Promise.withResolvers();
  const timer = setTimeout(() => abort(new Error(`Timeout after ${ms}ms`)), ms);
  try {
    return await Promise.race([fetch(url), timeout]);
  } finally {
    clearTimeout(timer);
  }
}

4. Iterator Helpers: map, filter, take, drop (ES2025)

Iterator Helpers sind eines der wichtigsten ES2025-Features für funktionale Datenverarbeitung. Das Problem: Iteratoren in JavaScript – von Generatoren bis zu Map-, Set- und DOM-Collection-Iteratoren – sind primitiv. Man muss sie erst in Arrays konvertieren, um .map(), .filter() oder .reduce() nutzen zu können. Die Konvertierung ist nicht nur umständlich, sie ist auch teuer: Sie materialisiert die gesamte Kollektion im Speicher. Iterator Helpers ermöglichen lazy Verkettung direkt auf dem Iterator – filter und map werden erst dann ausgeführt, wenn das Ergebnis tatsächlich konsumiert wird.

Die Methoden sind als Prototype-Methoden auf dem eingebauten Iterator-Prototyp definiert: Iterator.prototype.map, Iterator.prototype.filter, Iterator.prototype.take, Iterator.prototype.drop, Iterator.prototype.flatMap, Iterator.prototype.reduce, Iterator.prototype.toArray und Iterator.prototype.forEach. Alle Methoden außer reduce, toArray und forEach sind lazy – sie geben einen neuen Iterator zurück, ohne die Kette zu materialisieren. Das macht ES2025 Iterator Helpers besonders wertvoll bei großen Datensätzen, unendlichen Generatoren und Streaming-Szenarien.

5. Temporal API: Datum und Zeit endlich richtig (ES2025)

Die Temporal API ist das ambitionierteste ES2025-Feature und löst ein Problem, das JavaScript-Entwickler seit Jahrzehnten plagt: Das eingebaute Date-Objekt ist grundlegend fehlerhaft. Es kennt keine Zeitzone-aware Arithmetik, repräsentiert intern immer UTC als Millisekunden-Timestamp, hat keine vernünftige Arithmetik für Monate und Jahre, und seine API ist historisch inkonsistent. Bibliotheken wie Moment.js, date-fns und Luxon existieren hauptsächlich, weil Date so schlecht ist. Temporal ersetzt das alles mit einer vollständigen, modernen Datum-Zeit-Bibliothek in der Sprache selbst.

Die Temporal-Typen sind bewusst separiert: Temporal.PlainDate für ein Datum ohne Zeit und Zeitzone, Temporal.PlainTime für eine Uhrzeit ohne Datum, Temporal.PlainDateTime für Datum + Zeit ohne Zeitzone, Temporal.ZonedDateTime für Datum + Zeit + Zeitzone, und Temporal.Instant für einen absoluten Zeitpunkt (wie Date). Die Trennung erzwingt, dass man explizit über Zeitzonen nachdenkt – der häufigste Fehler bei Datumsverarbeitung. Arithmetik mit Temporal ist korrekt: Ein Monat addieren ergibt immer einen gültigen Monatsletzten, auch bei Februar.


// ES2025: Temporal API — correct date/time arithmetic without libraries
// Note: Use polyfill (@js-temporal/polyfill) until fully shipped

// PlainDate: date without time or timezone
const today = Temporal.Now.plainDateISO(); // '2026-05-10'
const nextMonth = today.add({ months: 1 }); // '2026-06-10'
const endOfQuarter = today.with({ month: 6, day: 30 }); // '2026-06-30'

// ZonedDateTime: date + time + timezone — correct DST handling
const meeting = Temporal.ZonedDateTime.from({
  year: 2026, month: 6, day: 15,
  hour: 10, minute: 0,
  timeZone: 'Europe/Berlin'
});
const inNewYork = meeting.withTimeZone('America/New_York');
console.log(inNewYork.toString()); // '2026-06-15T04:00:00-04:00[America/New_York]'

// Duration arithmetic — handles month-boundary correctly
const start = Temporal.PlainDate.from('2026-01-31');
const oneMonth = start.add({ months: 1 }); // '2026-02-28' — not March 3rd

// Compare and sort dates
const dates = ['2026-03-15', '2026-01-01', '2026-12-31']
  .map(d => Temporal.PlainDate.from(d))
  .sort(Temporal.PlainDate.compare); // built-in comparator

// Duration between two dates
const diff = today.until(nextMonth, { largestUnit: 'day' });
console.log(`${diff.days} days until next month`); // '31 days'

6. Dekoratoren (ES2025): Klassen und Methoden annotieren

Dekoratoren sind eines der langwartenden ES2025-Features, das TypeScript-Entwicklern bereits bekannt ist – allerdings in einer anderen, älteren Spec-Version. Die ES2025-Dekoratoren-Spezifikation ist grundlegend überarbeitet und unterscheidet sich von den TypeScript-Dekoratoren unter experimentalDecorators. Die neue Spec ist präziser, sicherer und konsistenter. Dekoratoren können auf Klassen, Klassenmethoden, Getter, Setter, Felder und Accessor-Felder angewendet werden. Sie sind Funktionen, die zur Definitionszeit der Klasse aufgerufen werden, nicht zur Ausführungszeit.

Der praktische Nutzen von Dekoratoren: Cross-Cutting-Concerns wie Logging, Memoization, Validierung, Rate-Limiting und Caching können als wiederverwendbare Funktionen implementiert und deklarativ auf Klassen angewendet werden, ohne AOP-Frameworks. Ein @memoize-Dekorator auf einer Klassenmethode cashet das Ergebnis anhand der Argumente – keine Code-Duplizierung, kein manuelles Wrapping. Ein @readonly-Dekorator auf einem Feld macht es nicht schreibbar. Ein @validate-Dekorator auf einem Setter prüft den Wert vor der Zuweisung. Die Dekorator-Composition – mehrere Dekoratoren auf einer Methode – ist klar definiert und von außen nach innen angewendet.

7. Weitere ES2024-Features: RegExp v-Flag, ArrayBuffer.resize

Die RegExp v-Flag (Unicode Sets) ist ein stilles, aber wichtiges ES2024-Feature. Sie aktiviert erweiterte Unicode-Unterstützung: Verschachtelte Zeichenklassen ([a-z&&[^aeiou]] für Konsonanten), Set-Operationen in Character Classes und korrekte Verarbeitung von Unicode-Strings mit Graphem-Clustern. Für internationale Anwendungen, die Namen, Adressen oder natürlichsprachliche Eingaben validieren, ist der v-Flag ein wichtiges Upgrade gegenüber dem u-Flag. Die Syntax ist abwärtskompatibel – vorhandene RegEx-Ausdrücke werden nicht beeinflusst.

ArrayBuffer.prototype.resize() und ArrayBuffer.prototype.transfer() sind ES2024-Features für effiziente binäre Datenverarbeitung. Statt einen neuen ArrayBuffer allozieren und Daten kopieren zu müssen, wenn sich die Größe ändert, kann man einen vorhandenen Buffer in-place vergrößern oder verkleinern. Das ist besonders relevant für WebAssembly-Interop, Audio-Processing und Netzwerk-Streaming, wo Puffergrößen dynamisch angepasst werden müssen. Die transfer()-Methode ermöglicht Zero-Copy-Übertragung eines Buffers in einen anderen Kontext – nützlich für Web Workers, die Daten ohne Kopie austauschen sollen.


// ES2024: RegExp v-flag — Unicode Sets and nested character classes
// Consonants only (letters minus vowels):
const consonants = /^[a-z&&[^aeiou]]+$/v;
console.log(consonants.test('bcdf')); // true
console.log(consonants.test('hello')); // false — contains vowels

// Unicode property escapes with set operations
const greekLetters = /^\p{Script=Greek}+$/v;
const notASCII = /^[^\p{ASCII}]+$/v;

// String properties (new in v-flag):
const emojiSeq = /^\p{RGI_Emoji}+$/v; // matches emoji grapheme clusters correctly

// ES2025: Iterator Helpers — lazy transformation chains
function* fibonacci() {
  let [a, b] = [0, 1];
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

// Take first 10 even Fibonacci numbers — no Array materialization until .toArray()
const evenFibs = fibonacci()
  .filter(n => n % 2 === 0) // lazy filter
  .take(10)                  // lazy take
  .toArray();                // materialize only here
console.log(evenFibs); // [0, 2, 8, 34, 144, 610, 2584, 10946, 46368, 196418]

// Iterator.from() wraps any iterable
const mapIter = Iterator.from(new Map([['a', 1], ['b', 2]]))
  .map(([key, val]) => `${key}=${val}`)
  .toArray(); // ['a=1', 'b=2']

8. Pattern Matching: Stage-3-Proposal im Überblick

Pattern Matching ist noch kein finalisiertes ES2025-Feature, befindet sich aber in Stage 3 und wird von vielen als das wichtigste kommende JavaScript-Feature betrachtet. Das match-Statement ermöglicht strukturelles Pattern-Matching ähnlich wie in Rust, Haskell oder Scala: Ein Wert wird gegen Muster verglichen, und der erste passende Zweig wird ausgeführt. Anders als switch prüft Pattern Matching nicht nur Gleichheit, sondern kann tief in Objekte schauen, auf Typen prüfen, Guards anwenden und Werte dekonstruieren.

Die vorgeschlagene Syntax nutzt match (value) { when Pattern: expression }. Patterns können Literale, Variablenbindungen, Array-Patterns, Object-Patterns und Guards (when condition) kombinieren. Ein match-Ausdruck auf eine Fetch-Response könnte auf { status: 200, body }, { status: 404 } und den Default-Fall matchen – jeder Zweig mit eigenem Ausdruck. Das eliminiert tiefe if-else-Ketten bei der Verarbeitung von API-Responses, Redux-Actions oder Discriminated Unions. TypeScript-Nutzer kennen das Konzept aus exhaustive Type Narrowing, aber Pattern Matching macht es zur Laufzeit-Prüfung in JavaScript selbst.

9. ES2024 vs. ES2025: Features im Vergleich

Der Unterschied zwischen ES2024-Features und ES2025-Features liegt sowohl im Umfang als auch in der aktuellen Verfügbarkeit. ES2024 ist vollständig spezifiziert und in modernen Laufzeiten implementiert. ES2025 enthält größere Features wie die Temporal API und Dekoratoren, die noch in der finalen Implementierungsphase sind.

Feature Spec Chrome Node.js
Object.groupBy / Map.groupBy ES2024 117+ 21+
Promise.withResolvers ES2024 119+ 22+
RegExp v-Flag ES2024 112+ 20+
Iterator Helpers ES2025 122+ 22+
Temporal API ES2025 Polyfill Polyfill
Dekoratoren ES2025 Flag/Polyfill Flag

Die Adoptionsstrategie für ES2024- und ES2025-Features hängt von der Zielumgebung ab. Features mit breiter Browser-Unterstützung wie Object.groupBy und Promise.withResolvers können heute ohne Transpiler oder Polyfill verwendet werden, wenn IE-Support nicht erforderlich ist. Für Temporal und Dekoratoren ist der @js-temporal/polyfill bzw. der Babel-Dekoratoren-Plugin der empfohlene Weg bis zur nativen Unterstützung.

Mironsoft

Moderne JavaScript-Entwicklung und ECMAScript-Adoption

Moderne JavaScript-Features sicher einführen?

Wir helfen euch dabei, ES2024- und ES2025-Features schrittweise in bestehende Codebasen zu integrieren – mit Transpiler-Setup, Polyfill-Strategie und Code-Review für moderne JavaScript-Patterns.

Codebase-Migration

Bestehenden Code auf moderne ES2024/ES2025-Patterns modernisieren

Build-Setup

Babel, TypeScript und Vite für neue JavaScript-Features konfigurieren

Team-Schulung

Workshop zu ES2024/ES2025-Features für JavaScript-Entwicklungsteams

10. Zusammenfassung und Adoptionsstrategie

Die ES2024- und ES2025-Features sind keine Spielzeuge für Early Adopters, sondern Antworten auf reale, jahrelang bekannte JavaScript-Defizite. Object.groupBy und Map.groupBy ersetzen komplexe reduce()-Muster. Promise.withResolvers standardisiert das Deferred-Pattern. Iterator Helpers bringen lazy Transformation auf alle Iteratoren ohne Array-Konvertierung. Die Temporal API macht Datums-Bibliotheken in den meisten Anwendungsfällen obsolet. Dekoratoren ermöglichen deklarative Cross-Cutting-Concerns ohne Framework-Overhead.

Die Adoptionsstrategie folgt dem Verfügbarkeits-Grad: ES2024-Features ohne Transpiler in modernen Projekten direkt einsetzen. ES2025-Features mit Polyfill oder Transpiler-Plugin je nach Browser-Target. TypeScript-Projekte profitieren durch Typ-Inferenz und frühe Syntax-Unterstützung. Der wichtigste Schritt ist das regelmäßige Lesen des TC39-Proposal-Repos und der MDN-Kompatibilitätstabellen – die JavaScript-Sprache entwickelt sich mit mehreren bedeutenden Ergänzungen pro Jahr weiter.

ES2024 & ES2025 Features — Das Wichtigste auf einen Blick

ES2024 – Heute nutzbar

Object.groupBy, Map.groupBy, Promise.withResolvers, RegExp v-Flag, ArrayBuffer.resize – alle in Chrome 117+ und Node.js 21+ ohne Polyfill verfügbar.

ES2025 – Mit Polyfill

Iterator Helpers (Chrome 122+), Temporal API (@js-temporal/polyfill), Dekoratoren (Babel-Plugin) – Stage-4-finalisiert, aber noch nicht überall nativ verfügbar.

Temporal API

Ersetzt Date-Bibliotheken: PlainDate, ZonedDateTime, korrekte Monats-Arithmetik, DST-aware Zeitzonenkonvertierung. Polyfill: @js-temporal/polyfill.

Adoptionsstrategie

TC39-Proposals und MDN-Kompatibilitätstabellen regelmäßig verfolgen. Features schrittweise nach Verfügbarkeit einführen, TypeScript für frühe Typ-Unterstützung nutzen.

11. FAQ: ES2024 und ES2025 JavaScript-Features

1ES2024 vs. ES2025?
ES2024: Object.groupBy, Promise.withResolvers, RegExp v-Flag, ArrayBuffer.resize. ES2025: Iterator Helpers, Temporal API, Dekoratoren. Beide haben Stage 4 erreicht, unterscheiden sich in der nativen Verfügbarkeit.
2Object.groupBy in Production?
Ja, ab Chrome 117+, Firefox 121+, Node.js 21+. Für ältere Browser core-js als Polyfill nutzen.
3Promise.withResolvers vs. Promise-Konstruktor?
Gibt { promise, resolve, reject } direkt zurück. Kein umständliches Herausziehen aus dem Konstruktor-Scope. Besonders nützlich wenn resolve direkt als Event-Listener übergeben werden soll.
4Warum Iterator Helpers?
Lazy Transformation direkt auf Iteratoren ohne Array-Materialisierung. filter, map, take, drop – erst ausgeführt wenn Ergebnis konsumiert. Ideal für große Datensätze und unendliche Generatoren.
5Temporal API: Stage 4?
Ja, Teil von ES2025. Noch nicht nativ in allen Browsern. Polyfill @js-temporal/polyfill für frühe Adoption empfohlen.
6ES2025-Dekoratoren vs. TypeScript experimentalDecorators?
Komplett andere Spec-Version. TypeScript 5.0 unterstützt beide Modi. Neue Projekte sollten die neue ES2025-Spec nutzen, nicht den alten experimentalDecorators-Modus.
7RegExp v-Flag wann nötig?
Bei Unicode Sets, verschachtelten Zeichenklassen und korrekter Graphem-Cluster-Verarbeitung. Wichtig für internationale Anwendungen mit Unicode-Eingaben und Emoji-Validierung.
8Pattern Matching – wann kommt es?
Aktuell Stage 3. Kein festes Erscheinungsdatum. Das TC39-Repository auf GitHub zeigt den aktuellen Stand. Frühestens ES2026.
9TC39-Proposals finden?
github.com/tc39/proposals – nach Stage gruppiert. MDN-Dokumentation und tc39.es für Spezifikationsstatus und Browser-Kompatibilität.
10Temporal ersetzt date-fns vollständig?
Für die meisten Anwendungsfälle ja. Arithmetik, Zeitzonen, Formatierung und Parsing sind abgedeckt. Sehr spezifische Formatter können noch Hilfsfunktionen erfordern.