Optional Chaining und Nullish Coalescing in JavaScript: Sicher auf Werte zugreifen
Wie du mit den Operatoren ?. und ?? tief verschachtelte Objekte ohne Abstürze ausliest und Standardwerte sauber setzt – ohne endlose if-Abfragen.
Kennst du diesen Fehler? TypeError: Cannot read properties of undefined. Er taucht fast immer dann auf, wenn du auf eine Eigenschaft zugreifst, die tief in einem Objekt liegt – und irgendwo auf dem Weg dorthin fehlt ein Zwischenobjekt. Früher hast du dagegen mit langen if-Ketten oder &&-Verkettungen gekämpft. Seit ES2020 gibt es dafür zwei kleine, aber mächtige Operatoren: Optional Chaining (?.) und Nullish Coalescing (??). In diesem Beitrag lernst du, wie beide funktionieren, wann du sie einsetzt und welche Fallstricke du vermeiden solltest.
Das Problem: verschachtelte Objekte und undefined
Stell dir vor, du bekommst ein Nutzerobjekt von einer API. Nicht jeder Nutzer hat eine Adresse hinterlegt. Greifst du trotzdem blind auf die Stadt zu, kracht es:
const user = { name: "Anna" };
// user.address ist undefined – der Zugriff auf .city wirft einen Fehler
console.log(user.address.city);
// TypeError: Cannot read properties of undefined (reading 'city')Der klassische Schutz dagegen war eine Kette aus Und-Verknüpfungen. Das funktioniert, wird aber schnell unleserlich, je tiefer die Struktur ist:
// Vor Optional Chaining: umständlich und schwer zu lesen
const city = user && user.address && user.address.city;
console.log(city); // undefined – aber immerhin kein AbsturzOptional Chaining: der ?.-Operator
Mit Optional Chaining schreibst du dieselbe Absicherung deutlich kürzer. Der Operator ?. prüft, ob der Wert links davon null oder undefined ist. Falls ja, bricht die Auswertung sofort ab und gibt undefined zurück – statt einen Fehler zu werfen.
const user = { name: "Anna" };
console.log(user.address?.city);
// undefined – kein Fehler, die Kette stoppt bei address
const user2 = { name: "Ben", address: { city: "Berlin" } };
console.log(user2.address?.city);
// "Berlin"Wichtig ist das Kurzschluss-Verhalten: Sobald ?. auf null oder undefined trifft, wird der Rest der Kette gar nicht mehr ausgewertet. Das gilt auch über mehrere Ebenen hinweg:
const data = {};
console.log(data.user?.profile?.settings?.theme);
// undefined – egal wie tief, es gibt keinen AbsturzOptional Chaining bei Methoden und Arrays
Der Operator kann mehr als nur Eigenschaften lesen. Mit ?.() rufst du eine Methode nur dann auf, wenn sie tatsächlich existiert. Und mit ?.[] greifst du sicher auf Array- oder dynamische Eigenschaften zu:
const api = {
logger: {
log: (msg) => console.log("LOG:", msg),
},
};
// Methode existiert -> wird aufgerufen
api.logger?.log?.("Alles bereit");
// LOG: Alles bereit
// Methode fehlt -> kein Aufruf, kein Fehler
api.tracker?.track?.("Klick");
// (passiert nichts)
// Sicherer Zugriff auf Array-Elemente
const users = [{ name: "Anna" }];
console.log(users?.[0]?.name); // "Anna"
console.log(users?.[5]?.name); // undefinedAchte auf die Klammer-Schreibweise: Bei Methoden schreibst du ?.(, bei Index-Zugriffen ?.[. Der Punkt gehört immer dazu.
Nullish Coalescing: der ??-Operator
Optional Chaining liefert dir bei fehlenden Werten undefined. Oft willst du stattdessen einen sinnvollen Standardwert setzen. Genau dafür gibt es ??: Er gibt den rechten Wert nur dann zurück, wenn der linke null oder undefined ist.
Der entscheidende Unterschied zum älteren ||-Operator: || greift bei allen falsy-Werten – also auch bei 0, "" oder false. Das führt zu subtilen Bugs, wenn diese Werte eigentlich gültig sind:
const settings = { volume: 0, label: "" };
// || behandelt 0 und "" faelschlich als "leer"
console.log(settings.volume || 50); // 50 (falsch! 0 war gewollt)
console.log(settings.label || "Neu"); // "Neu" (falsch! "" war gewollt)
// ?? greift NUR bei null oder undefined
console.log(settings.volume ?? 50); // 0 (korrekt)
console.log(settings.label ?? "Neu"); // "" (korrekt)
console.log(settings.color ?? "rot"); // "rot" (color fehlt -> Standard)Faustregel: Nimm ??, wenn 0, ein leerer String oder false gültige Werte sein können. Nimm || nur, wenn du wirklich jeden falsy-Wert ersetzen willst.
?. und ?? clever kombinieren
Ihre volle Stärke spielen beide Operatoren im Zusammenspiel aus: Erst liest du mit ?. sicher aus, dann fängst du das Ergebnis mit ?? ab und lieferst einen Standardwert.
function getTheme(user) {
return user?.profile?.settings?.theme ?? "hell";
}
console.log(getTheme({ profile: { settings: { theme: "dunkel" } } }));
// "dunkel"
console.log(getTheme({ name: "Anna" })); // "hell"
console.log(getTheme(null)); // "hell"Seit ES2021 gibt es außerdem den kombinierten Zuweisungsoperator ??=. Er setzt einen Wert nur dann, wenn die Variable aktuell null oder undefined ist:
const config = { retries: 0 };
config.retries ??= 3; // bleibt 0, weil 0 nicht nullish ist
config.timeout ??= 5000; // wird gesetzt, weil timeout fehlt
console.log(config); // { retries: 0, timeout: 5000 }Ein Hinweis zur Syntax: Du kannst ?? nicht ohne Klammern direkt mit && oder || mischen. a ?? b || c wirft einen Syntaxfehler. Schreibe stattdessen (a ?? b) || c, damit klar ist, was zuerst ausgewertet wird.
Fazit
Optional Chaining und Nullish Coalescing nehmen dir eine Menge defensiven Boilerplate-Code ab. Mit ?. greifst du sicher auf verschachtelte Eigenschaften, Methoden und Array-Elemente zu, ohne dass fehlende Zwischenwerte dein Programm zum Absturz bringen. Mit ?? setzt du saubere Standardwerte und vermeidest die klassische ||-Falle rund um 0, "" und false. Beide Operatoren werden von allen modernen Browsern und aktuellen Node.js-Versionen unterstützt. Nimm dir das nächste Mal, wenn du eine lange &&-Kette schreibst, kurz Zeit und ersetze sie durch ?. – dein zukünftiges Ich wird es dir danken.