JavaScript – Das Handbuch für die Praxis. David Flanagan
// => 1: Inkrementierung wurde (wegen "Kurzschließung") übersprungen.
Bedingte Aufrufausdrücke mit ?.() funktionieren für Methoden genauso wie für Funktionen. Da der Methodenaufruf jedoch auch den Zugriff auf Eigenschaften beinhaltet, sollten Sie sich einen Moment Zeit nehmen, um sicherzustellen, dass Sie die Unterschiede zwischen den folgenden Ausdrücken verstehen:
o.m() // Normaler (regulärer, nicht bedingter) Zugriff auf Eigenschaften,
// normaler Aufruf.
o?.m() // Bedingter Zugriff auf Eigenschaften, normaler Aufruf.
o.m?.() // Normaler Zugriff auf Eigenschaften, bedingter Aufruf.
Im ersten Ausdruck muss o ein Objekt mit einer Eigenschaft m und der Wert dieser Eigenschaft muss eine Funktion sein. Wenn im zweiten Ausdruck o null oder undefined ist, wird der Ausdruck zu undefined ausgewertet. Hat o aber einen anderen Wert, muss es eine Eigenschaft m besitzen, deren Wert eine Funktion ist. Und im dritten Ausdruck darf o nicht null oder undefined sein. Falls es keine Eigenschaft m besitzt oder wenn der Wert dieser Eigenschaft null ist, wird der gesamte Ausdruck zu undefined ausgewertet.
Der bedingte Aufruf mit ?.() ist – wie der bedingte Eigenschaftszugriff – eine der neuesten Funktionen von JavaScript. Stand Anfang 2020 wird auch diese neue Syntax in den aktuellen oder Betaversionen der meisten gängigen Browser unterstützt.
4.6Ausdrücke zur Objekterstellung
Ein Ausdruck zur Objekterstellung bzw. ein Objekterstellungsausdruck erstellt – erwartungsgemäß – ein neues Objekt und ruft eine (als Konstruktor bezeichnete) Funktion auf, um die Eigenschaften dieses Objekts zu initialisieren. Ausdrücke zur Objekterstellung ähneln den Aufrufausdrücken, abgesehen davon, dass ihnen das Schlüsselwort new vorangestellt wird:
new Object()
new Point(2,3)
Werden der Konstruktorfunktion in einem Objekterstellungsausdruck keine Argumente übergeben, kann die leere Klammer weggelassen werden:
new Object
new Date
Der Wert eines Objekterstellungsausdrucks ist das neu erstellte Objekt. Konstruktoren werden in Kapitel 9 ausführlicher erläutert.
4.7Operatoren im Überblick
Operatoren werden in JavaScript für arithmetische Ausdrücke, Vergleichsausdrücke, logische Ausdrücke, Zuweisungsausdrücke und anderes verwendet. Tabelle 4-1 fasst die Operatoren zusammen und dient als praktische Referenz.
Die meisten Operatoren werden durch Interpunktionszeichen wie + und = dargestellt. Nur einige wenige werden durch Schlüsselwörter wie delete und instanceof repräsentiert. Auch Schlüsselwortoperatoren sind gewöhnliche Operatoren, die sich in keiner Weise von denen unterscheiden, die durch Interpunktionszeichen ausgedrückt werden: Sie haben einfach nur eine etwas weniger kompakte Darstellung.
In Tabelle 4-1 sind die Operatoren anhand ihres Vorrangs sortiert. Die zuerst aufgeführten Operatoren haben Vorrang vor den nachfolgend aufgeführten. Operatoren, zwischen denen eine horizontale Linie steht, gehören unterschiedlichen Vorrangstufen an. Die Spalte mit der Überschrift »A« gibt die Assoziativität des Operators an. Der Wert kann L (von links nach rechts) oder R (von rechts nach links) betragen. Spalte »N« gibt die Anzahl von Operanden an. Die Spalte mit der Bezeichnung »Typen« führt die erwarteten Datentypen der Operanden und – nach dem Symbol → – den Ergebnistyp des Operators auf. Dabei habe ich mich an den Ergebniswerten orientiert, die der typeof-Operator zurückgibt (siehe Tabelle 4-3), und diese abgekürzt. Außerdem steht bel für »beliebig« und lval für »Lvalue«. In den Unterabschnitten im Anschluss an die Tabelle werden die Konzepte des Vorrangs, der Assoziativität und des Operandentyps erläutert. Die Operatoren selbst werden im Anschluss an diese Abschnitte einzeln beschrieben.
Tabelle 4-1: JavaScript-Operatoren
4.7.1Anzahl an Operanden
Operatoren können anhand der Anzahl der von ihnen erwarteten Operanden (ihrer Arität oder Stelligkeit) kategorisiert werden. Die meisten Operatoren in JavaScript – wie beispielsweise der Multiplikationsoperator * – sind binäre Operatoren, die zwei Ausdrücke zu einem komplexeren Ausdruck vereinen und dementsprechend zwei Operanden erwarten. JavaScript unterstützt darüber hinaus eine Reihe von unären Operatoren, die einen einzelnen Ausdruck in einen einzigen komplexeren Ausdruck umwandeln. Der –-Operator im Ausdruck –x ist ein unärer Operator, der auf dem Operanden x eine Negation durchführt. Schließlich unterstützt JavaScript einen ternären Operator, den Bedingungsoperator ?:, der drei Ausdrücke zu einem einzigen Ausdruck kombiniert.
4.7.2Operanden und Ergebnistyp
Einige Operatoren arbeiten mit Werten beliebiger Typen, aber die meisten erwarten Operanden eines spezifischen Typs und liefern auch einen Wert eines spezifischen Typs zurück. Die Spalte »Typen« in Tabelle 4-1 gibt (vor dem Pfeil) die Typen der Operanden und (nach dem Pfeil) den Ergebnistyp für die einzelnen Operatoren an.
Üblicherweise konvertieren die Operatoren in JavaScript den Typ ihrer Operanden bei Bedarf (siehe 3.9). Obwohl der Multiplikationsoperator * numerische Operanden erwartet, ist der Ausdruck »3« * »5« zulässig, da JavaScript die Operanden in Zahlen umwandeln kann. Und der Wert dieses Ausdrucks ist natürlich die Zahl 15, nicht der String »15«. Denken Sie bitte auch daran, dass jeder JavaScript-Wert entweder ein »irgendwie wahrer« truthy- oder ein »irgendwie falscher« falsy-Wert ist (im Sinne nicht-strikter Gleich- bzw. Ungleichheit) und Operatoren, die boolesche Operanden erwarten, deswegen mit Operanden beliebigen Typs arbeiten.
Das Verhalten einiger Operatoren ist vom Typ der verwendeten Operanden abhängig. Der auffälligste Fall ist der des +-Operators, der numerische Operanden addiert, String-Operanden hingegen verkettet. Gleichermaßen führen Vergleichsoperatoren wie < den Vergleich in Abhängigkeit vom Operandentyp auf numerische oder alphabetische Weise durch. Bei den Beschreibungen der einzelnen Operatoren werden ihre Typabhängigkeiten erläutert und die durchgeführten Umwandlungen angegeben.
Zuweisungsoperatoren und einige weitere der Operatoren, die in Tabelle 4-1 aufgeführt werden, erwarten einen Operanden vom Typ lval. Lvalue ist ein historischer Begriff für einen »Ausdruck, der legal auf der linken Seite eines Zuweisungsausdrucks verwendet werden darf«. In JavaScript sind Variablen, Objekteigenschaften und Array-Elemente Lvalues.
4.7.3Seiteneffekte von Operatoren
Die Auswertung eines einfachen Ausdrucks wie 2 * 3 wirkt sich nie auf den Zustand Ihres Programms aus, d.h., keine der in der Folge von Ihrem Programm ausgeführten Berechnungen wird von dieser Auswertung beeinträchtigt. Einige Ausdrücke haben jedoch Seiteneffekte – ihre Auswertung kann sich auf das Ergebnis späterer Auswertungen auswirken.