Modern JavaScript

Modern JavaScript (ES6+)

ES6 und die darauf folgenden Releases haben JavaScript von einer eigenwilligen Scriptsprache in ein Vergnügen beim Schreiben verwandelt. Hier sind die Features, die Sie jeden einzelnen Tag nutzen werden.

intermediate15 min readUpdated 15. Sept. 2026
js
// cart.js
const items = [
  { name: "Keyboard", price: 80, qty: 1 },
  { name: "Mouse", price: 40, qty: 2 },
];

const total = items
  .map(({ price, qty }) => price * qty)
  .reduce((sum, n) => sum + n, 0);

console.log(`Total: $${total}`);
Veröffentlicht
Juni 2015
Auch bekannt als
ES2015 / ES6
Seitdem
Ein Release pro Jahr
Größte Gewinne
Scope, Module, Async
Wichtigste Ergänzungen
Arrow, Destructuring, Spread
Kompatibilität
Universell in modernen Browsern

Praxis

Moderne Array-Methoden ausprobieren

Ändern Sie die Zahlen und beobachten Sie, wie sich die Summe aktualisiert.

Moderne Array-Methoden ausprobieren

Ändern Sie die Zahlen und beobachten Sie, wie sich die Summe aktualisiert.

Warum es wichtig ist

Warum modernes JavaScript wichtig ist

Weniger Boilerplate

Destructuring, Shorthand und Template Literals reduzieren unnötigen Code, sodass die Absicht im Vordergrund steht statt syntaktisches Rauschen.

Sichererer Scope

Block-scoped let und const ersetzen var und eliminieren eine ganze Klasse von Hoisting- und versehentlichen Global-Bugs.

Echte Module

import und export gaben JavaScript ein standardisiertes Modulsystem, wodurch Code-Sharing und Tree-Shaking endlich natürlich wurden.

Das Gesamtbild

Drei Weichenstellungen, die alles verändert haben

ES6 war nicht nur neue Syntax. Es hat verändert, wie Scope funktioniert, wie Code organisiert wird und wie Daten durch ein Programm fließen.

Deklarationen

let, const, arrow

Block-Scope und prägnante Funktionen haben verändert, wie alltäglicher Code geschrieben und gelesen wird.

Datenverarbeitung

Destructuring, spread

Das Zerlegen von Werten und deren Zusammenführen wurde expressiv statt repetitiv.

Komposition

Modules, classes

Standard-Module und Class-Syntax machten es einfacher, größere Programme zu organisieren und zu teilen.

ES6+ auf einen Blick

Die Features, zu denen Sie täglich greifen werden

let & const

Block-scoped Bindings, die Variablen vorhersehbar machen.

Arrow functions

Kurze Funktionssyntax mit lexikalischem this, perfekt für Callbacks.

Template literals

Mehrzeilige Strings und Interpolation mit Backticks und ${}.

Destructuring

Arrays und Objekte in einem einzigen Ausdruck in Variablen entpacken.

Spread & rest

Werte an einer Stelle ausbreiten oder sie in einer einzigen sammeln – mit denselben drei Punkten.

Modules

Code mit import und export in Dateien aufteilen statt globale Variablen zu nutzen.

Eine kurze Geschichte

Der Weg von ES5 bis heute

  1. 2009

    ES5

    Strict Mode, JSON und Array-Methoden wie map und filter werden zum Standard.

    09
  2. 2015

    ES6 / ES2015

    Das bisher größte Update — let, const, Arrows, Classes, Promises, Module und mehr.

    15
  3. 2017

    async / await

    Asynchroner Code liest sich endlich wie synchroner Code.

    17
  4. 2020

    Optional chaining

    ?. und ?? ersetzen endlose defensive Null-Checks.

    20
  5. Heute

    Jährliche Releases

    TC39 veröffentlicht jeden Juni eine neue, abwärtskompatible Edition des Standards.

    Heute

Der vollständige Leitfaden

Modern JavaScript (ES6+): Alles was Sie wissen müssen

Was ist ES6+?

Im Juni 2015 erhielt JavaScript sein bisher größtes Update. ECMAScript 2015, besser bekannt als ES6, führte Block-Scoping, Arrow Functions, Klassen, Module, Promises und vieles mehr ein. Das Komitee, welches die Sprache pflegt, verpflichtete sich darauf, fortan jedes Jahr eine neue Edition zu veröffentlichen. „ES6+“ ist so zur Kurzbezeichnung für diese gesamte moderne Ära geworden.

Du musst nicht jedes einzelne Feature lernen. Eine Handvoll davon macht den Großteil des täglichen Codes aus – und genau diese werden in diesem Guide behandelt. Das gemeinsame Thema all dieser Neuerungen ist simpel: Drücke dich präziser aus, aber mit weniger unnötigem Boilerplate.

let und const

Das älteste Feature ist zugleich das wichtigste. var ist function-scoped und wird auf eine Weise gehoisted, die viele überrascht. let und const sind block-scoped, sie existieren also nur innerhalb des nächstgelegenen { }.

// scope.js
if (true) {
  let message = "inside";
  const limit = 10;
}

// message and limit are not defined out here

const verhindert die Neuzuweisung der Bindung, wodurch deine Absicht deutlich wird: dieser Name wird nicht auf etwas anderes verweisen. Es friert den Wert jedoch nicht ein, sodass ein const Array weiterhin mutiert werden kann. Nutze standardmäßig const, let wenn eine Neuzuweisung tatsächlich nötig ist, und betrachte var als Teil der Historie.

Arrow Functions

Arrow Functions bieten eine kürzere Syntax mit einem wichtigen verhaltensbezogenen Unterschied: Sie besitzen kein eigenes this. Sie erben this aus dem umschließenden Scope, was bei Callbacks fast immer das gewünschte Verhalten ist.

// arrows.js
const add = (a, b) => a + b;

const square = (n) => {
  return n * n;
};

const names = ["Ada", "Grace", "Linus"];
const upper = names.map((name) => name.toUpperCase());

Wenn der Body aus einem einzigen Ausdruck besteht, können die geschweiften Klammern und return weggelassen werden. Klammern um einen einzelnen Parameter sind optional. Da Arrow Functions this erfassen, eignen sie sich ideal für Event-Handler und Array-Methoden, sind jedoch weniger geeignet für Objekt-Methoden, die ein eigenes this benötigen.

Template-Literals

Backticks ermöglichen die Erstellung von Strings, die sich über mehrere Zeilen erstrecken und Ausdrücke mittels ${ } interpolieren.

// message.js
const name = "Ada";
const role = "engineer";

const greeting = `Hello, ${name}!
You are logged in as a ${role}.`;

Template-Literals unterstützen zudem Tagged Templates. Hierbei erhält eine Funktion die literalen Teile und die interpolierten Werte separat. Dieser Mechanismus bildet die Grundlage für viele Templating- und Styling-Libraries.

Destructuring

Destructuring entpackt Werte aus Arrays und Objekten in Variablen, wodurch viele repetitive Zugriffe auf Eigenschaften entfallen.

// destructure.js
const user = { name: "Ada", age: 36, city: "London" };
const { name, age, city = "Unknown" } = user;

const coords = [51.5, -0.12];
const [lat, lng] = coords;

function greet({ name }) {
  return `Hello, ${name}`;
}

Du kannst beim Destructuring Variablen umbenennen (const { name: userName } = user), Standardwerte angeben und direkt in der Parameterliste einer Funktion destrukturieren – ein Muster, das ständig bei React props und Konfigurationsobjekten verwendet wird.

Spread und Rest

Die gleichen drei Punkte erfüllen je nach Position zwei komplementäre Aufgaben.

// spread.js
const a = [1, 2, 3];
const b = [4, 5];

const combined = [...a, ...b];       // spread: expand
const copy = { ...user, age: 37 };   // shallow clone + override

function sum(...numbers) {           // rest: collect
  return numbers.reduce((t, n) => t + n, 0);
}

Spread kopiert Werte in ein neues Array oder Objekt, was die Grundlage für immutable Updates bildet. Rest fasst verbleibende Argumente oder Elemente in einem einzigen Array zusammen. Zusammen machen sie die Arbeit mit Collections wesentlich angenehmer.

Standardparameter und Shorthand

Funktionen können Standardwerte deklarieren, und Objekt-Literale können die Shorthand-Schreibweise nutzen, wenn der Eigenschaftsname mit einer Variable übereinstimmt.

// config.js
function connect({ host = "localhost", port = 8080 } = {}) {
  return `${host}:${port}`;
}

const name = "Ada";
const user = { name, greet() { return `Hi, ${this.name}`; } };

Standardwerte werden nur dann ausgewertet, wenn das Argument undefined ist, was in der Regel das gewünschte Verhalten ist. Shorthand-Properties und -Methoden reduzieren das Rauschen in Code, der stark auf Objekten basiert.

Optional Chaining und Nullish Coalescing

Diese beiden Operatoren, die 2020 eingeführt wurden, haben unzählige defensive Prüfungen überflüssig gemacht.

// safe.js
const city = user?.address?.city;
const name = input ?? "anonymous";

user?.profile?.onLogin?.();

?. führt einen Short-Circuit zu undefined aus, wenn der Wert auf der linken Seite null oder undefined ist. ?? bietet einen Fallback nur dann, wenn die linke Seite null oder undefined ist – im Gegensatz zu || werden 0, "" oder false nicht als fehlend behandelt.

Array-Methoden

Der Array-Prototyp ist vollgepackt mit Methoden, die die Absicht beschreiben, anstatt die Loop-Mechanik in den Vordergrund zu stellen.

// arrays.js
const products = [
  { name: "Keyboard", price: 80, inStock: true },
  { name: "Mouse", price: 40, inStock: false },
  { name: "Cable", price: 10, inStock: true },
];

const names = products.map((p) => p.name);
const cheap = products.filter((p) => p.price < 50);
const total = products.reduce((sum, p) => sum + p.price, 0);
const available = products.some((p) => p.inStock);
const allCheap = products.every((p) => p.price < 100);
const mouse = products.find((p) => p.name === "Mouse");

map transformiert, filter selektiert, reduce reduziert eine Liste auf einen einzelnen Wert, find gibt den ersten Treffer zurück und some/every prüfen eine Bedingung. Sie lassen sich chainen, mutieren das ursprüngliche Array nicht und lesen sich wie eine Beschreibung dessen, was man erreichen möchte.

Module

ES-Module ermöglichen es, Code auf mehrere Dateien aufzuteilen und nur das zu teilen, was Sie explizit auswählen.

// math.js
export function add(a, b) {
  return a + b;
}

export const PI = 3.14159;
export default function subtract(a, b) {
  return a - b;
}
// app.js
import subtract, { add, PI } from "./math.js";

Named Exports können pro Datei mehrfach vorkommen und werden über ihren Namen importiert. Ein Default Export ist ein einzelner Hauptwert. Module haben ihren eigenen Scope, werden nur einmal ausgewertet und ermöglichen es Bundlern, ungenutzten Code mittels Tree-Shaking zu entfernen.

Klassen

Klassen bieten eine klare Syntax für objektorientierten Code, die auf dem bestehenden Prototyp-System von JavaScript aufbaut.

// user.js
class User {
  #secret = "hidden"; // private field

  constructor(name) {
    this.name = name;
  }

  get greeting() {
    return `Hello, ${this.name}`;
  }

  static create(name) {
    return new User(name);
  }
}

class Admin extends User {
  constructor(name) {
    super(name);
    this.role = "admin";
  }
}

extends und super steuern die Vererbung, static definiert Methoden direkt an der Klasse und # kennzeichnet wirklich private Felder. Unter der Haube handelt es sich immer noch um Prototypen, aber die Syntax ist wesentlich einfacher zu lesen.

Weitere nützliche Features

  • Map und Set für Key-Value-Collections und eindeutige Werte, die für diese Zwecke eine bessere Semantik bieten als einfache Objekte und Arrays.
  • for…of zum Iterieren über Arrays, Strings, Maps, Sets und jedes andere Iterable.
  • Exponentiation mit **, sodass 2 ** 10 anstelle von Math.pow(2, 10) verwendet wird.
  • Iteratoren und Generatoren für Lazy Sequences, benutzerdefinierte Iterationen und pausierbare Funktionen.
  • Object.entries / fromEntries zur Konvertierung zwischen Objekten und Arrays von Paaren.

Best Practices

  • Standardmäßig const verwenden; let nur bei Neu-Zuweisungen nutzen.
  • Arrow Functions für Callbacks bevorzugen, reguläre Funktionen für Methoden, die this benötigen.
  • Destructuring in den Parametern nutzen, um die erforderliche Struktur explizit zu machen.
  • Den Spread-Operator für immutable Updates verwenden, anstatt gemeinsam genutzte Daten zu mutieren.
  • Auf ?. und ?? zurückgreifen, bevor verschachtelte Guards geschrieben werden.
  • Bei der Transformation von Daten Array-Methoden gegenüber handgeschriebenen Schleifen bevorzugen.
  • Module klein halten und nur die minimal notwendige Oberfläche exportieren.

Häufige Fehler

  • Die Annahme, dass const ein Objekt unveränderlich (immutable) macht – es verhindert lediglich die Neuzuweisung (rebinding).
  • Die Verwendung einer Arrow-Function als Objektmethode, wodurch der Bezug auf this verloren geht.
  • Die Verwendung von || für Standardwerte, wenn 0 oder "" gültige Werte sind; verwenden Sie stattdessen ??.
  • Das Spread-Operating nur eine Ebene tief und die Erwartung eines Deep Clones.
  • Das Vermischen von require und import im selben Modulsystem, ohne die Interoperabilität zu verstehen.
  • Das Verketten von zu vielen Array-Methoden zu einer unlesbaren Pipeline.

Wie geht es weiter?

Die moderne Syntax ist das Vokabular; das DOM und asynchrones JavaScript sind die Bereiche, in denen du dieses Wissen anwendest. Sobald sich Promises und Module natürlich anfühlen, verwandelt die Fetch API diese Fähigkeiten in echte Anwendungen.

Zugriff auf verschachtelte Daten

Optional Chaining und Nullish Coalescing ersetzen Ketten von &&-Prüfungen.

Bevorzugt
const city =
  user?.address?.city ?? "Unknown";
Vermeiden
const city =
  user && user.address &&
  user.address.city
    ? user.address.city
    : "Unknown";

Transformation einer Liste

map und reduce drücken die Absicht klarer aus und vermeiden manuelle Akkumulator-Variablen.

Bevorzugt
const names = users
  .filter((u) => u.active)
  .map((u) => u.name);
Vermeiden
const names = [];
for (let i = 0; i < users.length; i++) {
  if (users[i].active) {
    names.push(users[i].name);
  }
}

Häufig gestellte Fragen

Häufig gestellte Fragen

Keep learning

Related topics from the roadmap.

$ Lernen Sie jetzt

Bereit, ES6+ Features zu lernen?

Unser interaktives Tutorial führt Sie Schritt für Schritt durch ES6+ Features — mit Quizzen und echtem Code, den Sie im Browser ausführen können.