Zum Inhalt springen

1.4 Moderne Sprachmittel

Zu Zen-Modus wechseln

Nach dieser Einheit kannst du:

  • Werte mit Destructuring aus Objekten und Arrays holen, auch umbenannt, mit Standardwert und direkt in der Parameterliste.
  • Kopien mit Spread anlegen, erklären, warum sie flach sind, und Argumente mit Rest einsammeln.
  • verschachtelte Daten mit ?. und ?? robust lesen und Code mit export und import auf Module verteilen.

Eine Wetter- oder Fahrplan-App bekommt ihre Daten als JSON von einem Server, und nicht jedes Feld ist immer befüllt. Klassisch geschrieben wird daraus eine Kette von Zuweisungen und if-Abfragen, bevor die App überhaupt etwas anzeigt. Mit den Sprachmitteln dieser Einheit schrumpft derselbe Code auf wenige Zeilen, und die App bricht nicht mehr ab, wenn ein Feld fehlt.

flowchart LR
    accTitle: Optional Chaining liest unvollständige Daten ohne Absturz
    server["JSON vom Server"] --> full["mit Feld wind"]
    server --> missing["ohne Feld wind"]
    full --> show1["Anzeige der<br/>Windstärke"]
    missing --> show2["Anzeige: keine Angabe<br/>statt Absturz"]

Abb. 1.10: Mit ?. und ?? zeigt die App einen Ersatztext, wenn ein Feld fehlt, statt abzubrechen (eigene Darstellung).

Diese Sprachmittel sind keine Spielerei: Ab Kapitel 7 stehen sie in fast jeder Zeile React-Code. Wer sie sicher liest, versteht dort Props und Zustandsänderungen auf Anhieb.

  • Destructuring (Zerlegen): holt Werte aus einem Objekt oder Array heraus und legt sie in eigene Variablen.
  • Spread: ... packt den Inhalt eines Objekts oder Arrays in ein neues aus.
  • Rest: ... sammelt übrige Felder oder Argumente in einem Objekt oder Array ein.
  • Optional Chaining (?.): bricht einen Zugriff ohne Fehler ab, sobald ein Glied null oder undefined ist.
  • Modul: eine Datei, die ausdrücklich exportiert, was andere Dateien importieren dürfen.

Vier Sprachmittel, ohne die kein aktuelles JavaScript-Projekt auskommt:

Destructuring (Zerlegen) holt Werte aus einem Objekt oder Array heraus und legt sie in eigene Variablen.

// without destructuring
const filename = clip.filename;
const durationSeconds = clip.durationSeconds;
// with destructuring - same result, one line
const { filename, durationSeconds } = clip;

Die Variablennamen entsprechen dabei den Feldnamen; die Reihenfolge in den geschweiften Klammern spielt keine Rolle. Bei Arrays ist es umgekehrt: Dort entscheidet die Position, und die Namen sind frei wählbar.

const [first, second] = durations; // by position
const [, , third] = durations; // skip entries with commas

Vier Varianten, die im Jahresverlauf ständig vorkommen. Für diese Beispiele hat clip zusätzlich das verschachtelte Feld metadata: { codec: "h264" }:

// 1. rename while unpacking (the field is called filename, the variable name)
const { filename: name } = clip;
console.log(name); // "intro.mp4"
// 2. default value, applied when the field is undefined
const { fps = 25 } = clip;
console.log(fps); // 25
// 3. unpack nested structures
const { metadata: { codec } } = clip;
console.log(codec); // "h264"
// 4. rest: collect everything not named above into one object
const { filename, ...rest } = clip; // rest has all remaining fields
console.log(rest); // { durationSeconds: 90, tags: [...], fps: 25, metadata: {...} }

Besonders häufig steht Destructuring direkt in der Parameterliste. Die Funktion nimmt dann weiterhin ein Objekt entgegen, benennt aber in der Signatur, welche Felder sie tatsächlich braucht:

function describe({ filename, fps = 25 }) {
return `${filename} @ ${fps} fps`;
}
describe(clip); // called with the whole object

Beispielprojekt: 01_typescript_examples/ex11_destructuring

Das hat zwei praktische Folgen: Der Aufrufer muss sich keine Parameterreihenfolge merken, und die Signatur dokumentiert die Abhängigkeiten der Funktion. Genau in dieser Form tauchen ab dem React-Kapitel die Props jeder Komponente auf.

Das Objekt clip hat die Felder filename, durationSeconds und fps. const { filename, fsp } = clip holt filename über den gleichen Namen und bekommt intro.mp4. Für fsp gibt es kein Feld, die Variable ist still undefined, ohne Fehlermeldung
Abb. 1.11: Destructuring sucht Felder nach dem Namen, ein falscher Name ergibt still undefined (eigene Darstellung).
Auflösung

a ist 0, b ist null, c ist 25. Der Standardwert beim Destructuring greift nur, wenn das Feld undefined ist, also fehlt. 0 und sogar null werden übernommen. Das ist strenger als ?? aus Einheit 1.2, das auch bei null ersetzt.

Beide schreiben sich ..., arbeiten aber in entgegengesetzte Richtungen: Spread packt aus, Rest sammelt ein. Welches von beiden gemeint ist, verrät die Position - links von einem = oder in einer Parameterliste sammelt es, sonst packt es aus.

Spread schreibt den Inhalt eines Objekts oder Arrays in ein neues hinein:

const copy = { ...clip }; // shallow copy
const changed = { ...clip, fps: 50 }; // copy with one field overridden
const merged = { ...defaults, ...userSettings }; // later wins on conflict
const all = [...listA, ...listB]; // concatenate
const withExtra = [...durations, 150]; // append without touching the original
const maximum = Math.max(...durations); // spread as function arguments

Zwei Punkte, die man dabei wissen muss. Erstens gilt bei Objekten: Bei gleichem Feldnamen gewinnt der spätere Eintrag, deshalb steht fps: 50 hinter dem Spread und nicht davor. Zweitens ist die Kopie flach (shallow): Verschachtelte Objekte und Arrays werden nicht mitkopiert, sondern weiterhin geteilt.

const copy = { ...clip };
copy.filename = "outro.mp4"; // fine: the original keeps its filename
copy.tags.push("final"); // careful: clip.tags changed too - same array
clip und copy sind zwei eigene Objekte mit eigenem filename, intro.mp4 und outro.mp4. Ihre Felder tags zeigen beide auf dasselbe Array opener, draft; ein push über copy.tags ändert deshalb auch clip.tags
Abb. 1.12: Spread kopiert die oberste Ebene; das verschachtelte Array teilen sich Original und Kopie (eigene Darstellung).

Für verschachtelte Daten wird deshalb auf jeder betroffenen Ebene gespreadet ({ ...clip, tags: [...clip.tags, "final"] }) oder gleich structuredClone(clip) verwendet.

Rest ist die Gegenrichtung: Er sammelt, was übrig bleibt.

function sum(...values) { // collect all arguments into an array
return values.reduce((total, v) => total + v, 0);
}
sum(1, 2, 3); // values is [1, 2, 3]
function logRequest(method, ...details) { } // rest must come last

Beispielprojekt: 01_typescript_examples/ex12_spread_rest

Das Muster { ...object, field: newValue } - Kopie mit geänderten Feldern statt Änderung am Original - ist im React-Kapitel die Standardtechnik für Zustandsänderungen. Der Grund dafür ist dort ein handfester: React erkennt Änderungen daran, dass ein neues Objekt vorliegt; eine Änderung am bestehenden bleibt unbemerkt. Es lohnt sich, das Muster jetzt schon zu verinnerlichen.

const city = order?.customer?.address?.city; // undefined instead of crash
const fps = clip.metadata?.fps ?? 25; // combined with ??

Beispielprojekt: 01_typescript_examples/ex13_optional_chaining

?. bricht die Kette ohne Fehler ab, sobald ein Glied null/undefined ist. Zusammen mit ?? ergibt das den robusten Zugriff auf verschachtelte, möglicherweise unvollständige Daten, wie sie von fremden APIs kommen.

Wo begegnet dir das? Eine Wetter- oder Fahrplan-App bekommt ihre Daten als JSON von einem Server, und nicht jedes Feld ist immer befüllt: Für manche Station fehlt die Verspätung, für manchen Ort die Windstärke. Eine Zeile wie data.current?.wind?.speed ?? "keine Angabe" zeigt dann einen Ersatztext, statt dass die ganze Anzeige mit einem Fehler abbricht.

timecode.js
export function framesToTimecode(frameCount, fps = 25) { /* ... */ }
export const DEFAULT_FPS = 25;
// main.js
import { framesToTimecode, DEFAULT_FPS } from "./timecode.js";

Beispielprojekt: 01_typescript_examples/ex14_modules

Jede Datei ist ein Modul; exportiert wird explizit, importiert namentlich. Damit Node eine .js-Datei eindeutig als Modul behandelt, gehört in die package.json des Projekts der Eintrag "type": "module" (oder die Datei heißt .mjs). Fehlt er, erkennt Node 24 die import-Syntax zwar selbst und führt die Datei aus, meldet aber bei jedem Start die Warnung MODULE_TYPELESS_PACKAGE_JSON, weil es die Datei zweimal einlesen muss. Was es mit dieser package.json auf sich hat, behandelt das nächste Kapitel.

Auflösung

original.tags ist danach ["opener", "draft"]. Spread kopiert nur flach, copy.tags und original.tags sind dasselbe Array. Unverändert bleibt das Original mit const copy = { ...original, tags: [...original.tags] }; oder mit structuredClone(original).

  1. Fehlt das Feld, ist die Variable undefined: Destructuring prüft nichts. const { fsp } = clip; (Tippfehler) ergibt klaglos undefined, und der Fehler zeigt sich erst dort, wo die Variable benutzt wird. In TypeScript wird daraus ein Compile-Fehler.
  2. Die Kopie mit Spread für eine tiefe halten: Verschachtelte Arrays und Objekte teilen sich Kopie und Original. Jede betroffene Ebene spreaden oder structuredClone verwenden.
  3. Feld vor dem Spread überschrieben: In { fps: 50, ...clip } gewinnt das fps aus clip, weil der spätere Eintrag gewinnt. Das geänderte Feld gehört hinter den Spread.
  4. Vergessenes "type": "module": Node 24 führt die Datei trotzdem aus, warnt aber bei jedem Start mit MODULE_TYPELESS_PACKAGE_JSON. Steht in der package.json dagegen "type": "commonjs", bricht import mit Cannot use import statement outside a module ab.
  • javascript.info: Destructuring assignment - alle Varianten mit kleinen Aufgaben samt Lösung zum Selbsttesten.
  • javascript.info - ausführliches, frei zugängliches JavaScript-Tutorial mit Übungen, auch zu Spread, Rest und Modulen.
  • Node.js-Dokumentation: Syntax detection - wie Node 24 entscheidet, ob eine .js-Datei ein Modul ist.
  • MDN Web Docs: JavaScript - die Nachschlage-Referenz für jeden Operator, auch ?. und ??.

Du kannst dir diese Einheit kostenlos mit der Vorlesefunktion deines Browsers oder Betriebssystems vorlesen lassen (etwa „Laut vorlesen” in Edge), ohne Konto und ohne Upload; die Codebeispiele liest du dabei am Bildschirm mit. Freiwillig kannst du mit Google NotebookLM (Google-Konto nötig) aus diesem öffentlichen Text eine gesprochene Zusammenfassung erzeugen, auch auf Deutsch.

Du kannst jetzt:

  • Werte mit Destructuring aus Objekten und Arrays holen, auch umbenannt, mit Standardwert und direkt in der Parameterliste.
  • Kopien mit Spread anlegen, erklären, warum sie flach sind, und Argumente mit Rest einsammeln.
  • verschachtelte Daten mit ?. und ?? robust lesen und Code mit export und import auf Module verteilen.
  • Aufgabe 01 - TypeScript-Spickzettel, Stufe Wesentlich_vollständig (Module) und Stufe PlusPlus (flache Kopie und ?? untersuchen)
  • Destructuring → javascript.info: Destructuring assignment
  • Verhalten von Node ohne "type": "module" (Warnung MODULE_TYPELESS_PACKAGE_JSON) und mit "type": "commonjs" → eigener Test mit Node.js 24.11.1 (Oktober 2026); Node.js-Dokumentation: Syntax detection
  • Spread, Rest, Optional Chaining und Module allgemein → MDN Web Docs: JavaScript und javascript.info
  • Standardwerte beim Destructuring (0, null, fehlendes Feld) → eigener Test mit Node.js 24.11.1 (Oktober 2026)
  • Abb. 1.10 (Wetter-App mit fehlendem Feld, Mermaid-Diagramm), Abb. 1.11 (Destructuring mit Tippfehler), Abb. 1.12 (flache Kopie mit Spread) → eigene Darstellung
  • Oliver Maurhart (MAO)
  • Michael Gabriel (GAM)

CC-BY-SA

https://qiz.at/rules