JavaScript/Operatoren/Optional Chaining Operator
Der optional chaining Operator ?.
ist ein binärer Operator, der mit einer Verkettung von Objektzugriffen nur fortfährt, wenn das Objekt, auf das der Zugriff erfolgen soll, auch vorhanden ist. Andernfalls ist das Ergebnis undefined
.
Er wird als Ersatz für den normalen Punkt-Operator benutzt, oder als Präfix für Index-Zugriff oder Funktionsaufruf.
let obj1 = {
x: 17,
y() { return "Hallo"; }
},
arr1 = [ 7, 8, 9 ],
obj2 = null,
arr2 = undefined;
// Normales Objekt, normales Array
console.log(obj1.x, obj1["x"], obj1.y()) // 17 17 Hallo
console.log(arr1[0], arr1[2])) // 7 9
// Variable enthält null oder undefined
console.log(obj2.x, obj2["x"], obj2.y()) // TypeError
console.log(arr2[0], arr2[2])) // TypeError
// optional chaining operator to the rescue
console.log(obj2?.x, obj2?.["x"], obj2?.y()) // undefined undefined undefined
console.log(arr2?.[0], arr2?.[2])) // undefined undefined
Beschreibung
Der optional chaining Operator ist syntaktischer Zucker für die oft auftretende Problemstellung, dass an einer Stelle im Programm ein ermittelter Wert ein Objekt oder ein Array sein kann, oder auch nicht. Man muss verifizieren, dass dieser Wert nicht undefined
oder null
ist, bevor man ihn wie ein Objekt oder ein Array nutzen kann. Verzichtet man auf diese Prüfung, droht ein Programmabbruch mit einem TypeError.
Durch den optional chaining Operator kann man einfach annehmen, dass man ein Objekt oder ein Array hätte. Erweist sich die Annahme als falsch, sorgt der Operator dafür, dass das Ergebnis des ungültigen Zugriffs undefined
ist, statt einen TypeError zu werfen.
Besonders wertvoll ist er, wenn man einer Kette von Eigenschaften folgen muss - daher auch sein Name. Vergleichen Sie:
let temp1 = obj ? obj.x : undefined;
let temp2 = temp1 ? temp1.y : undefined;
let ergebnis = temp2 ? temp2.z : undefined;
let ergebnis = obj?.x?.y?.z;
Der Operator kann nicht nur für die Punkt-Notation verwendet werden, sondern auch für die Index-Notation und für Funktionsaufrufe. Im Gegensatz beispielsweise zum existential Operator in CoffeeScript muss der Punkt aber immer geschrieben werden, auch wenn die Index-Schreibweise verwendet wird oder ein Funktionsaufruf erfolgt.
result = obj1?.x
result = obj1?["x"]
result = obj1?(123)
result = obj1?.x;
result = obj1?.["x"];
result = obj1?.(123);
Der optional chaining Operator ist auch in Szenarien einsetzbar, wo Objekteigenschaften, Arrayelemente und Funktionsaufrufe bunt gemischt sind. Stellen Sie sich ein Objekt vor, das in seinen Eigenschaften Arrays von Funktionen enthält. Gibt's nicht, meinen Sie? Denken Sie an EventListener...
const eventRegistry = {
click: [
event => obj2.handleClick(event),
event => obj3.buttonClicked(event),
event => myClickHandler(event)
]
};
function callFirstClickHandler() {
eventRegistry?.click?.[0]?.(new MouseEvent('click'));
}
Ohne optional chaining müsste callFirstClickHandler
etliche Prüfungen durchführen und für die Zwischenwerte temporäre Variablen erstellen.
Kompatibilität
Der optional chaining Operator wurde mit ECMAScript 2020 Teil der Sprache und wurde Anfang 2020 von den Browserherstellern ausgerollt. In Node.js wurde er mit Version 14 verfügbar, in TypeScript in Version 3.7. Transpiler wie Babel oder auch TypeScript ermöglichen eine Übersetzung des Codes in ein kompatibles Format.