JavaScript/Operatoren/Optional Chaining Operator

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

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.

Beispiel
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:

Die Welt ohne den optional chaining Operator
let temp1 = obj ? obj.x : undefined;
let temp2 = temp1 ? temp1.y : undefined;
let ergebnis = temp2 ? temp2.z : undefined;
So einfach kann es sein!
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.

CoffeeScript
result = obj1?.x
result = obj1?["x"]
result = obj1?(123)
JavaScript und TypeScript
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...

Komplexe Strukturen
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.