JavaScript – Das Handbuch für die Praxis. David Flanagan
!(p || q) === (!p && !q) // => true: Für alle Werte von p und q.
4.11Zuweisungsausdrücke
JavaScript verwendet den =-Operator, um einer Variablen oder Eigenschaft einen Wert zuzuweisen, zum Beispiel:
i = 0; // Setzt die Variable i auf 0.
o.x = 1; // Setzt die Eigenschaft x von Objekt o auf 1.
Der =-Operator erwartet, dass der Operand auf seiner linken Seite ein Lvalue ist: eine Variable oder eine Objekteigenschaft (oder ein Array-Element). Als rechtsseitigen Operanden erwartet er einen beliebigen Wert eines beliebigen Typs. Der Wert eines Zuweisungsausdrucks ist der Wert seines rechtsseitigen Operanden. Als Seiteneffekt weist der =-Operator den Wert auf seiner rechten Seite der Variablen oder Eigenschaft auf seiner linken Seite zu, damit spätere Referenzen auf die Variable oder Eigenschaft zu diesem Wert ausgewertet werden.
Obwohl Zuweisungsausdrücke in der Regel recht einfach sind, können Sie gelegentlich darauf stoßen, dass der Wert eines Zuweisungsausdrucks als Teil eines größeren Ausdrucks genutzt wird. Beispielsweise können Sie einen Wert im selben Ausdruck sowohl testen wie auch zuweisen:
(a = b) === 0
Wenn Sie derartige Dinge tun, sollten Sie darauf achten, dass Ihnen der Unterschied zwischen den Operatoren = und === vollkommen klar ist! Beachten Sie bitte, dass = einen sehr geringen Vorrang hat und deshalb meist Klammern erforderlich sind, wenn der Wert einer Zuweisung in einem größeren Ausdruck verwendet werden soll.
Der Zuweisungsoperator ist rechtsassoziativ. Das bedeutet, dass mehrere Zuweisungsoperatoren in einem Ausdruck von rechts nach links ausgewertet werden. Sie können also Code wie diesen schreiben, um mehreren Variablen den gleichen Wert zuzuweisen:
i = j = k = 0; // Initialisiert 3 Variablen mit dem Wert 0.
4.11.1Zuweisung mit Operation
Neben dem normalen Zuweisungsoperator = unterstützt JavaScript eine Reihe weiterer Zuweisungsoperatoren, bei denen die eigentliche Zuweisung mit einer anderen Operation kombiniert wird. Beispielsweise führt der +=-Operator sowohl eine Addition als auch eine Zuweisung aus. Der Ausdruck
total += salesTax;
ist gleichwertig mit diesem:
total = total + salesTax;
Wie Sie sich vielleicht schon gedacht haben, kann der +=-Operator mit Strings und Zahlen umgehen. Bei numerischen Operanden führt er Addition und Zuweisung aus, bei String-Operanden Verkettung und Zuweisung.
Ähnliche Operatoren sind -=, *=, &= usw. Tabelle 4-2 zeigt sie in einer Übersicht.
Tabelle 4-2: Zuweisungsoperatoren
Operator | Beispiel | Äquivalent |
+= | a += b | a = a + b |
-= | a -= b | a = a - b |
*= | a *= b | a = a * b |
/= | a /= b | a = a / b |
%= | a %= b | a = a % b |
**= | a **= b | a = a ** b |
<<= | a <<= b | a = a << b |
>>= | a >>= b | a = a >> b |
>>>= | a >>>= b | a = a >>> b |
&= | a &= b | a = a & b |
|= | a |= b | a = a | b |
^= | a ^= b | a = a ^ b |
In den meisten Fällen ist der Ausdruck
a op= b
(mit op als beliebigem Operator) äquivalent zum Ausdruck
a = a op b
In der ersten Zeile wird der Ausdruck a einmal ausgewertet, in der zweiten zweimal. Die beiden Fälle unterscheiden sich also nur dann, wenn a Seiteneffekte hat, weil dieser Ausdruck beispielsweise einen Funktionsaufruf oder eine Inkrementierungsoperation enthält. Die beiden folgenden Zuweisungen sind beispielsweise nicht gleich:
data[i++] *= 2;
data[i++] = data[i++] * 2;
4.12Auswertungsausdrücke
Wie viele interpretierte Programmiersprachen kann JavaScript Strings interpretieren, die spracheigenen Quellcode enthalten, und diese auswerten, um einen Wert zu erzeugen. In JavaScript benutzt man dazu die globale Funktion eval():
eval("3+2") // => 5
Die dynamische Auswertung von Strings mit Quellcode ist ein mächtiges Sprachmerkmal, das man in der Praxis allerdings fast nie braucht. Wenn Sie eval() einsetzen, sollten Sie noch einmal sorgfältig überdenken, ob Sie es tatsächlich benötigen. Damit eval() nicht zu einem Sicherheitsrisiko wird, sollten Sie vor allem niemals einen String, der auf irgendwelche Benutzereingaben zurückgeht, an eval() übergeben. Bei einer so komplizierten Sprache wie JavaScript besteht keine Möglichkeit, Benutzereingaben derart von möglichem Schadcode zu bereinigen, dass die Eingaben sicher mit eval() verwendet werden können. Wegen dieser Sicherheitsprobleme verwenden einige Webserver den HTTP-Header Content-Security-Policy, um eval() für eine ganze Website zu deaktivieren.
In den folgenden Unterabschnitten besprechen wir zuerst die allgemeine Verwendung von eval(), bevor wir zu zwei eingeschränkten Versionen kommen, die geringere Auswirkungen auf den JavaScript-Optimierer haben.
Ist eval() eine Funktion oder ein Operator?
eval() ist eine Funktion, wird aber trotzdem in diesem Kapitel über Ausdrücke und Operatoren behandelt, weil es eigentlich ein Operator hätte sein sollen. Die eval()-Funktion gibt es bereits seit den frühesten Versionen von JavaScript, aber die Sprachentwickler und Programmierer des Interpreters haben sie seitdem kontinuierlich mit Einschränkungen versehen, die zu immer größerer Ähnlichkeit mit einem Operator geführt haben. Moderne JavaScript-Interpreter führen eine Vielzahl von Codeanalysen und -optimierungen durch. Allgemein gesagt: Ruft eine Funktion eval() auf, kann der Interpreter diese Funktion nicht mehr optimieren. Weil eval() als Funktion vorliegt, kann man ihr einen anderen Namen geben – und das ist das Problem:
let f = eval;
let g = f;
In