JavaScript – Das Handbuch für die Praxis. David Flanagan
dasselbe wie 2**8, nicht wie 4**3. Ausdrücke wie -3**2 sind von Natur aus mehrdeutig. Je nach relativer Präzedenz von unärem Minus- und Exponentialoperator könnte dieser Ausdruck (-3)**2 oder -(3**2) bedeuten. Verschiedene Programmiersprachen handhaben diese Situation unterschiedlich, und statt hier eine eindeutige Position zu beziehen, wurde für JavaScript einfach festgelegt, dass es zu einem Syntaxfehler führt, in diesem Fall die Klammern wegzulassen. Dadurch ist man gezwungen, einen eindeutigen Ausdruck zu formulieren. Der Exponentialoperator ** ist der neueste arithmetische Operator in JavaScript: Er wurde mit ES2016 zu JavaScript hinzugefügt. Schon seit den frühesten Versionen von JavaScript existiert die Funktion Math.pow(), die genau die gleiche Operation ausführt.
Der /-Operator teilt seinen ersten Operanden durch seinen zweiten Operanden. Wenn Sie an Programmiersprachen gewöhnt sind, die Ganz- und Gleitkommazahlen unterscheiden, erwarten Sie bei der Teilung einer ganzen Zahl durch eine andere vielleicht ein ganzzahliges Ergebnis. Aber da in JavaScript alle Zahlen Gleitkommazahlen sind, liefern alle Divisionsoperationen Gleitkommazahlen als Ergebnis: 5/2 wird zu 2.5 berechnet, nicht zu 2. Die Division durch null liefert plus oder minus unendlich (Infinity oder -Infinity), während 0/0 zu NaN ausgewertet wird: In keinem dieser Fälle wird ein Fehler ausgelöst.
Der %-Operator berechnet den ersten Operanden modulo den zweiten Operanden. Es wird also eine Modulodivision durchgeführt, d.h. die Operation liefert den Rest, der verbleibt, wenn man den ersten Operanden ganzzahlig durch den zweiten Operanden teilt. Das Vorzeichen des Ergebnisses entspricht dem Vorzeichen des ersten Operanden. Beispielsweise wird 5 % 2 zu 1 und -5 % 2 zu -1 ausgewertet.
Obgleich der Modulooperator üblicherweise mit ganzzahligen Operanden verwendet wird, funktioniert er auch bei Gleitkommawerten. 6.5 % 2.1 ergibt beispielsweise 0.2.
4.8.1Der +-Operator
Der binäre +-Operator addiert numerische Operanden oder verkettet String-Operanden:
1 + 2 // => 3
"hello" + " " + "there" // => "hello there"
"1" + "2" // => "12"
Wenn die Werte der Operanden entweder nur Zahlen oder nur Strings sind, ist offensichtlich, was der +-Operator mit ihnen macht. In allen anderen Fällen sind hingegen Typumwandlungen erforderlich. Die Operation, die letztendlich ausgeführt wird, ist von diesen Umwandlungen abhängig. Die Umwandlungsregeln für + bevorzugen die String-Verkettung: Ist einer der Operanden ein String oder ein Objekt, das in einen String umgewandelt werden kann, wird der andere Operand in einen String umgewandelt, und eine String-Verkettung wird durchgeführt. Eine Addition erfolgt nur dann, wenn keiner der Operanden stringartig ist.
Formal verhält sich der +-Operator folgendermaßen:
Ist einer seiner Operanden ein Objekt, wird dieses mit dem in 3.9.3 beschriebenen Algorithmus in einen Primitivwert konvertiert. Date-Objekte werden über ihre toString()-Methode umgewandelt, alle anderen Objekte über ihre valueOf()-Methode, falls diese Methode einen primitiven Wert liefert. Die meisten Objekte besitzen jedoch keine nützliche valueOf()-Methode und werden deswegen ebenfalls über toString() umgewandelt.
Ist nach der Objekt-zu-Primitivwert-Umwandlung einer der Operanden ein String, wird der andere ebenfalls in einen String umgewandelt, und eine String-Verkettung wird durchgeführt.
Andernfalls werden beide Operanden in Zahlen (oder NaN) konvertiert, die daraufhin addiert werden.
Hier einige Beispiele:
1 + 2 // => 3: Addition.
"1" + "2" // => "12": Verkettung.
"1" + 2 // => "12": Verkettung nach Zahl-zu-String-Umwandlung.
1 + {} // => "1[object Object]": Verkettung nach Objekt-zu-String-
// Umwandlung.
true + true // => 2: Addition nach Boolescher-Wert-zu-Zahl-Umwandlung.
2 + null // => 2: Addition nach Umwandlung von null in 0.
2 + undefined // => NaN: Addition nach Umwandlung von undefined in NaN.
Schließlich ist noch zu beachten, dass der Operator + bei Zeichenketten und Zahlen möglicherweise nicht assoziativ ist. Oder anders ausgedrückt: Das Ergebnis kann von der Reihenfolge abhängen, in der die Operationen durchgeführt werden.
Ein Beispiel:
1 + 2 + " blind mice" // => "3 blind mice"
1 + (2 + " blind mice") // => "12 blind mice"
Da die erste Zeile keine Klammern enthält und der +-Operator linksassoziativ ist, werden zunächst die beiden Zahlen addiert, bevor ihre Summe mit dem String verkettet wird. In der zweiten Zeile ändern Klammern die Abfolge dieser Operationen: Die Zahl 2 wird mit dem String verkettet, und es wird ein neuer String erzeugt. Dann wird die Zahl 1 mit dem neuen String verkettet, um das endgültige Ergebnis zu erzeugen.
4.8.2Unäre arithmetische Operatoren
Unäre Operatoren modifizieren den Wert eines einzelnen Operanden, um einen neuen Wert hervorzubringen. In JavaScript haben alle unären Operatoren einen hohen Vorrang und sind rechtsassoziativ. Die arithmetischen unären Operatoren (+, -, ++ und --) wandeln alle ihre einzigen Operanden bei Bedarf in eine Zahl um. Man sollte im Hinterkopf behalten, dass + und - sowohl als unäre als auch als binäre Operatoren verwendet werden.
Es gibt die folgenden unären arithmetischen Operatoren:
Unäres Plus (+)
Der unäre arithmetische Operator wandelt seinen Operanden in eine Zahl (oder in NaN) um und gibt diesen umgewandelten Wert zurück. Wird er auf einem Operanden verwendet, der bereits eine Zahl ist, wird keine Aktion durchgeführt. Dieser Operator darf nicht mit BigInt-Werten verwendet werden, da diese nicht in reguläre Zahlen konvertiert werden können.
Unäres Minus (-)
Wenn - als unärer Operator verwendet wird, wandelt er seinen Operanden gegebenenfalls in eine Zahl um und ändert dann das Vorzeichen des Ergebnisses.
Inkrement (++)
Der ++-Operator inkrementiert seinen einzigen Operanden. Der Operand muss ein Lvalue sein (eine Variable, ein Array-Element oder eine Objekteigenschaft). Der Operator wandelt seinen Operanden bei Bedarf in eine Zahl um, fügt dieser 1 hinzu und weist den inkrementierten Wert wieder der Variablen, dem Element oder der Eigenschaft zu.
Der Rückgabewert des ++-Operators ist von seiner Stellung in Bezug auf den Operanden abhängig. Steht er vor seinem Operanden – man spricht von einem Präinkrement –, inkrementiert er den Wert und wird dann zum inkrementierten Wert des Operanden ausgewertet. Steht er hinter dem Operanden – dann spricht man von einem Postinkrement –, inkrementiert er den Operanden, wird aber zum nicht inkrementierten Wert des Operanden ausgewertet. Den Unterschied verdeutlichen diese beiden Codezeilen:
let i = 1, j = ++i; // i und j sind beide 2.
let n = 1, m = n++; // n ist 2, m ist 1.
Beachten Sie, dass der Ausdruck x++ nicht immer das Gleiche ist wie x=x+1. Der ++-Operator führt keine String-Verkettung durch: Er wandelt seinen Operanden immer in eine Zahl um und inkrementiert sie. Wenn x den String-Wert »1« hat, entspricht ++x der Zahl 2, während x+1 zum String »11« ausgewertet wird.
Bitte beachten Sie außerdem, dass wegen JavaScripts automatischer Semikolonergänzung kein Zeilenumbruch zwischen den Postinkrementoperator und den vor ihm stehenden Operanden gesetzt werden darf. Tritt dieser Fall dennoch auf, behandelt JavaScript den Operanden als eine eigenständige Anweisung und fügt vor ihm ein Semikolon ein.
Der Inkrementoperator wird