JavaScript Optional Chaining (?.)
Lerne den JavaScript-Optional-Chaining-Operator (?.) zum sicheren Zugriff auf verschachtelte Objekteigenschaften, Methoden und dynamische Schlüssel.
Der Optional-Chaining-Operator ?. ist eine kurze, sichere Möglichkeit, einen Wert tief in einer Kette verbundener Objekte zu lesen, wenn eines der Glieder in dieser Kette möglicherweise nicht existiert. Anstatt einen Fehler zu werfen, hört er einfach auf und gibt undefined zurück. Dieses Kapitel erläutert das Problem, das er löst, die drei Formen, die er annimmt, und die wenigen Regeln, die man für die korrekte Verwendung kennen muss.
Das Problem: Fehlende Eigenschaften lesen
Stell dir vor, du hast ein user-object und möchtest die Stadt aus einem verschachtelten address-object lesen. Wenn address fehlt, wirft der Zugriff auf eine Eigenschaft davon einen Fehler:
let user = {}; // a user without an address
console.log(user.address.city);
// TypeError: Cannot read properties of undefined (reading 'city')Der Grund ist, dass user.address undefined ist und der Versuch, .city aus undefined zu lesen, nicht erlaubt ist. Das ist eine häufige Situation, wenn Daten aus einer API, einem Formular oder einer Datenbank stammen, bei denen manche Felder optional sind.
Bevor ?. existierte, halfen sich Entwickler mit &&-Ketten oder verschachtelten Prüfungen. Diese funktionieren, sind jedoch ausführlich und wiederholen die Eigenschaftsnamen:
let user = {};
// The old way with the && operator
let city = user && user.address && user.address.city;
console.log(city); // undefined
// Or with an even longer ternary
let city2 = user ? (user.address ? user.address.city : undefined) : undefined;
console.log(city2); // undefinedWie Optional Chaining funktioniert
Der Optional-Chaining-Operator ?. stoppt die Auswertung, wenn der Wert davor null oder undefined ist, und gibt undefined zurück, anstatt einen Fehler zu werfen. Dieses Verhalten nennt man Kurzschlussauswertung (short-circuiting).
Hier ist die gleiche Abfrage, jetzt sicher und lesbar:
Wenn user.address undefined ist, gibt der Ausdruck user?.address?.city still undefined zurück. Wenn die Daten vorhanden sind, liest die Kette bis zu city durch.
?. behandelt nur null und undefined als „fehlend". Andere falsy-Werte wie 0, '' (leerer string) oder false sind echte Werte, daher läuft die Kette normal durch sie hindurch.
Es schützt nur den Wert links davon
Dies ist die wichtigste Regel, und diejenige, bei der Einsteiger am häufigsten einen Fehler machen. Das ?. prüft nur den Wert unmittelbar zu seiner Linken, nicht die gesamte Kette.
Betrachte a?.b.c:
- Wenn
anulloderundefinedist, findet eine Kurzschlussauswertung für den gesamten Ausdruck statt und es wirdundefinedzurückgegeben. - Wenn aber
aexistiert undbnulloderundefinedist, ist.cimmer noch ein normaler Zugriff — und er wirft einen Fehler.
let a = { b: null };
console.log(a?.b); // null — fine, a exists
console.log(a?.b.c); // TypeError: Cannot read properties of null (reading 'c')Die Lösung besteht darin, ?. an jeder Stelle zu setzen, wo ein Wert legitimerweise fehlen kann:
let a = { b: null };
console.log(a?.b?.c); // undefined — no errorDie Regel ist also einfach: Setze ?. direkt nach jedem Wert, der möglicherweise nicht vorhanden ist, nicht nur am Anfang der Kette.
Kurzschlussauswertung stoppt die gesamte Kette
Wenn der Teil vor ?. null oder undefined ist, wird der Rest des Ausdrucks überhaupt nicht ausgewertet. Das schließt Funktionsaufrufe und weitere Eigenschaftszugriffe ein, die danach folgen.
Das ist eine nützliche Garantie: Nichts nach einem fehlenden Glied bekommt die Chance zu laufen oder Nebeneffekte zu verursachen.
Die drei Formen von Optional Chaining
?. ist kein eigenständiger Operator — es ist ein Syntaxkonstrukt, das in drei Formen vorkommt, eine für jede Möglichkeit, auf einen Wert zuzugreifen.
?. für den Eigenschaftszugriff
Verwende obj?.prop, um eine Eigenschaft zu lesen, wenn obj möglicherweise null oder undefined ist.
let user = { name: 'John' };
console.log(user?.name); // John
console.log(user?.surname); // undefined (key missing, but no error)?.() für den Methodenaufruf
Verwende obj.method?.(), um eine Methode nur dann aufzurufen, wenn sie existiert. Das ist praktisch, wenn ein object eine bestimmte Methode möglicherweise implementiert oder auch nicht.
Wenn greet keine Funktion ist (weil sie fehlt), überspringt ?.() den Aufruf und gibt undefined zurück, anstatt TypeError: greet is not a function zu werfen.
?.[] für dynamische Schlüssel
Verwende obj?.[key], wenn du eine Eigenschaft mit der Klammernotation liest — zum Beispiel einen dynamischen Schlüssel, der in einer Variable gespeichert ist.
let user = { name: 'Alice' };
let key = 'name';
console.log(user?.[key]); // Alice
let nobody = null;
console.log(nobody?.[key]); // undefined (no error)Optional Chaining ist zum Lesen, nicht zum Schreiben
Du kannst ?. zum Lesen eines Werts verwenden und sogar zum sicheren delete einer Eigenschaft. Du kannst es jedoch nicht auf der linken Seite einer Zuweisung verwenden.
let user = null;
// Reading is fine
console.log(user?.name); // undefined
// Deleting is fine — delete is skipped if user is null
delete user?.name; // no error
// Assignment does NOT work — this is a syntax error
// user?.name = 'John'; // SyntaxErrorDer Grund ist, dass es sinnlos wäre, etwas zuzuweisen, wenn die linke Seite fehlt, daher erlaubt die Sprache dies nicht.
Optional Chaining nicht übermäßig einsetzen
?. ist ein präzises Werkzeug: Verwende es nur dort, wo der Wert links davon tatsächlich optional ist. Es überall zu verwenden ist ein Fehler, da es echte Bugs verbergen kann.
Wenn du zum Beispiel einen Eigenschaftsnamen falsch schreibst, gibt ?. stillschweigend undefined zurück, anstatt das Problem aufzuzeigen:
let user = { name: 'John' };
console.log(user?.nmae); // undefined — typo hidden, no error to alert youWenn eine Variable wie user immer existieren muss (zum Beispiel ist sie ein erforderliches Argument), greife direkt mit user.address?.city darauf zu, nicht mit user?.address?.city. Auf diese Weise wirft ein tatsächlich fehlender user weiterhin frühzeitig einen Fehler, was dir hilft, Bugs zu finden, anstatt sie zu verbergen.
Kombination mit Nullish Coalescing
Optional Chaining gibt undefined zurück, wenn ein Glied fehlt, was sich perfekt mit dem Nullish-Coalescing-Operator ?? kombinieren lässt, um einen Standardwert bereitzustellen.
Hier wird user?.name zu undefined ausgewertet, und ?? liefert dann den Fallbackwert 'Anonymous'. Diese Kombination ist eine der häufigsten Anwendungen von ?. in der Praxis.
Browser-Unterstützung
Optional Chaining ist Teil der ES2020-Spezifikation. Es wird in allen modernen Browsern (Chrome, Firefox, Safari und Edge) sowie in Node.js 14 und höher unterstützt, sodass du es in aktuellen Umgebungen ohne Transpiler verwenden kannst. Mehr zu den Werten, die es prüft, erfährst du unter JavaScript-Datentypen und Objektmethoden und this.