Get to know MDN better
Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.
Die Operatorenrangfolge bestimmt, wie Operatoren im Verhältnis zueinander geparst werden. Operatoren mit höherer Rangfolge werden die Operanden von Operatoren mit niedrigerer Rangfolge.
Betrachten Sie einen Ausdruck, der durch die folgende Darstellung beschreibbar ist, wobei sowohl OP1 als auch OP2 Platzhalter für OPeratoren sind.
a OP1 b OP2 cDie obige Kombination hat zwei mögliche Interpretationen:
(a OP1 b) OP2 c a OP1 (b OP2 c)Welche Interpretation die Sprache annimmt, hängt von der Identität von OP1 und OP2 ab.
Wenn OP1 und OP2 unterschiedliche Rangfolgen (siehe Tabelle unten) haben, wird der Operator mit der höheren Rangfolge zuerst ausgeführt und die Assoziativität spielt keine Rolle. Beachten Sie, dass Multiplikation eine höhere Rangfolge hat als Addition und zuerst ausgeführt wird, auch wenn die Addition im Code zuerst geschrieben ist.
Innerhalb von Operatoren mit derselben Rangfolge gruppiert die Sprache diese nach Assoziativität. Linksassoziativität (von links nach rechts) bedeutet, dass sie als (a OP1 b) OP2 c interpretiert wird, während Rechtsassoziativität (von rechts nach links) bedeutet, dass sie als a OP1 (b OP2 c) interpretiert wird. Zuweisungsoperatoren sind rechtsassoziativ, daher können Sie schreiben:
mit dem erwarteten Ergebnis, dass a und b den Wert 5 erhalten. Dies liegt daran, dass der Zuweisungsoperator den zugewiesenen Wert zurückgibt. Zuerst wird b auf 5 gesetzt. Dann wird auch a auf 5 gesetzt — den Rückgabewert von b = 5, d.h. der rechte Operand der Zuweisung.
Ein weiteres Beispiel: Der einzigartige Exponentialoperator hat eine Rechtsassoziativität, während andere arithmetische Operatoren eine Linksassoziativität haben.
Operatoren werden zuerst nach Rangfolge und dann, für benachbarte Operatoren mit derselben Rangfolge, nach Assoziativität gruppiert. Wenn Sie Division und Exponentiation mischen, kommt die Exponentiation immer vor der Division. Zum Beispiel ergibt 2 ** 3 / 3 ** 2 0.8888888888888888, weil es dasselbe ist wie (2 ** 3) / (3 ** 2).
Für präfixunäre Operatoren nehmen wir den folgenden Muster an:
OP1 a OP2 bwobei OP1 ein Präfixunärer Operator und OP2 ein binärer Operator ist. Wenn OP1 eine höhere Rangfolge als OP2 hat, würde es als (OP1 a) OP2 b gruppiert; andernfalls wäre es OP1 (a OP2 b).
Wenn der unäre Operator auf dem zweiten Operand steht:
a OP2 OP1 bDann muss der binäre Operator OP2 eine niedrigere Rangfolge als der unäre Operator OP1 haben, damit er als a OP2 (OP1 b) gruppiert wird. Zum Beispiel ist das folgende ungültig:
Da + eine höhere Rangfolge als yield hat, würde dies zu (a + yield) 1 werden — aber da yield ein reserviertes Wort in Generatorfunktionen ist, wäre dies ein Syntaxfehler. Glücklicherweise haben die meisten unären Operatoren eine höhere Rangfolge als binäre Operatoren und leiden nicht unter diesem Fallstrick.
Wenn wir zwei Präfixunäre Operatoren haben:
OP1 OP2 aDann muss der unäre Operator, der näher an dem Operand ist, OP2, eine höhere Rangfolge als OP1 haben, damit er als OP1 (OP2 a) gruppiert wird. Es ist möglich, es andersherum zu machen und mit (OP1 OP2) a zu enden:
Da await eine höhere Rangfolge als yield hat, würde dies (await yield) 1 werden, was bedeutet, dass auf einen Bezeichner namens yield gewartet wird, also ein Syntaxfehler. Ebenso, wenn Sie new !A; haben, wird, da ! eine niedrigere Rangfolge als new hat, dies zu (new !) A, was offensichtlich ungültig ist. (Dieser Code sieht sowieso unsinnig aus, da !A immer ein Boolescher Wert ist, keine Konstruktorfunktion.)
Für postfixunäre Operatoren (namentlich ++ und --) gelten die gleichen Regeln. Glücklicherweise haben beide Operatoren eine höhere Rangfolge als jeder binäre Operator, sodass die Gruppierung immer so ist, wie Sie es erwarten würden. Außerdem, da ++ zu einem Wert und nicht zu einer Referenz evaluiert, können Sie keine mehrfachen Inkremente zusammenketten.
Die Operatorenrangfolge wird rekursiv behandelt. Zum Beispiel betrachten Sie diesen Ausdruck:
Zuerst gruppieren wir Operatoren mit unterschiedlichen Rangstufen in absteigender Reihenfolge der Rangstufen.
Innerhalb der *// Gruppe, da sie beide linksassoziativ sind, würde der linke Operand gruppiert werden.
Beachten Sie, dass die Operatorenrangfolge und -assoziativität nur die Auswertungsreihenfolge von Operatoren (die implizite Gruppierung) und nicht die Reihenfolge der Auswertung von Operanden beeinflusst. Die Operanden werden immer von links nach rechts ausgewertet. Die höher priorisierten Ausdrücke werden immer zuerst ausgewertet, und ihre Ergebnisse werden dann gemäß der Operatorenrangfolge zusammengesetzt.
Wenn Sie mit Binärbäumen vertraut sind, denken Sie an eine Post-Order Traversierung.
/ ┌────────┴────────┐ echo("left", 4) ** ┌────────┴────────┐ echo("middle", 3) echo("right", 2)Nachdem alle Operatoren richtig gruppiert wurden, würden die binären Operatoren einen Binärbaum bilden. Die Auswertung beginnt von der äußersten Gruppe — das ist der Operator mit der niedrigsten Rangfolge (/ in diesem Fall). Der linke Operand dieses Operators wird zuerst ausgewertet, was aus höher priorisierten Operatoren (wie einem Aufrufausdruck echo("left", 4)) bestehen kann. Nachdem der linke Operand ausgewertet wurde, wird der rechte Operand auf die gleiche Weise ausgewertet. Daher würden alle Blattknoten — die echo()-Aufrufe — von links nach rechts besucht, unabhängig von der Rangfolge der Operatoren, die sie verbinden.
Im vorherigen Abschnitt sagten wir: "Die höher priorisierten Ausdrücke werden immer zuerst ausgewertet" — das ist im Allgemeinen wahr, muss jedoch mit der Anerkennung der Kurzschlusslogik ergänzt werden, bei der ein Operand möglicherweise überhaupt nicht ausgewertet wird.
Kurzschlusslogik ist ein Fachbegriff für bedingte Auswertung. Zum Beispiel in dem Ausdruck a && (b + c), wenn a falsch ist, wird der Unterausdruck (b + c) nicht einmal ausgewertet, selbst wenn er gruppiert ist und daher eine höhere Rangfolge hat als &&. Wir könnten sagen, dass der logische Und-Operator (&&) "kurzgeschlossen" ist. Neben logischem Und gehören zu den anderen kurzgeschlossenen Operatoren logisches Oder (||), der Nullish Coalescing Operator (??) und der optionale Verkettungsoperator (?.).
Beim Auswerten eines kurzgeschlossenen Operators wird stets der linke Operand ausgewertet. Der rechte Operand wird nur ausgewertet, wenn der linke Operand das Ergebnis der Operation nicht bestimmen kann.
Hinweis: Das Verhalten der Kurzschlusslogik ist in diesen Operatoren integriert. Andere Operatoren würden immer beide Operanden auswerten, unabhängig davon, ob das tatsächlich nützlich ist — zum Beispiel wird NaN * foo() immer foo aufrufen, selbst wenn das Ergebnis niemals etwas anderes als NaN wäre.
Das vorherige Modell einer Post-Order Traversierung gilt weiterhin. Allerdings wird die Sprache, nachdem der linke Unterbaum eines kurzgeschlossenen Operators besucht wurde, entscheiden, ob der rechte Operand ausgewertet werden muss. Wenn nicht (z. B. weil der linke Operand von || bereits wahr ist), wird das Ergebnis direkt zurückgegeben, ohne den rechten Unterbaum zu besuchen.
Betrachten Sie diesen Fall:
Nur C() wird ausgewertet, obwohl && eine höhere Rangfolge hat. Das bedeutet nicht, dass || in diesem Fall eine höhere Rangfolge hat — es ist genau weil (B() && A()) eine höhere Rangfolge hat, dass es als Ganzes vernachlässigt wird. Wenn es umsortiert wird als:
Dann würde der Kurzschlusseffekt von && nur verhindern, dass B() ausgewertet wird, aber weil A() && B() als Ganzes false ist, würde C() trotzdem ausgewertet.
Allerdings beachten Sie, dass Kurzschlusslogik das endgültige Auswertungsergebnis nicht ändert. Es beeinflusst nur die Auswertung der Operanden, nicht wie Operatoren gruppiert werden — wenn die Auswertung von Operanden keine Nebeneffekte hat (zum Beispiel Ausgabe an die Konsole, Zuweisung an Variablen, Auslösen eines Fehlers), wäre die Kurzschlusslogik überhaupt nicht wahrnehmbar.
Die Zuweisungsgegenstücke dieser Operatoren (&&=, ||=, ??=) sind ebenfalls kurzgeschlossen. Sie sind so kurzgeschlossen, dass die Zuweisung überhaupt nicht erfolgt.
Die folgende Tabelle listet Operatoren in der Reihenfolge von der höchsten Rangfolge (18) zur niedrigsten Rangfolge (1) auf.
Mehrere allgemeine Hinweise zur Tabelle:
| 18: Gruppierung | n/a | Grouping (x) |
[1] |
| 17: Zugriff und Aufruf | von links nach rechts | Mitgliederzugriff x.y |
[2] |
| Optionale Verkettung x?.y |
|||
| n/a |
Berechneter Mitgliederzugriff x[y] |
[3] | |
| new mit Argumentliste new x(y) |
[4] | ||
|
Funktionsaufruf x(y) |
|||
| import(x) | |||
| 16: new | n/a | new ohne Argumentliste new x |
|
| 15: Postfix-Operatoren | n/a |
Postfix-Inkrement x++ |
[5] |
|
Postfix-Dekrement x-- |
|||
| 14: Präfix-Operatoren | n/a |
Präfix-Inkrement ++x |
[6] |
|
Präfix-Dekrement --x |
|||
|
Logisches NICHT !x |
|||
|
Bitweises NICHT ~x |
|||
|
Unäres Plus +x |
|||
|
Unäre Negation -x |
|||
| typeof x | |||
| void x | |||
| delete x | [7] | ||
| await x | |||
| 13: Exponentiierung | von rechts nach links |
Exponentiation x ** y |
[8] |
| 12: Multiplikative Operatoren | von links nach rechts |
Multiplikation x * y |
|
|
Division x / y |
|||
|
Rest x % y |
|||
| 11: Additive Operatoren | von links nach rechts |
Addition x + y |
|
|
Subtraktion x - y |
|||
| 10: Bitweises Verschieben | von links nach rechts |
Linksschiebung x << y |
|
|
Rechtsschiebung x >> y |
|||
|
Unsigned-Rechtsschiebung x >>> y |
|||
| 9: Relationale Operatoren | von links nach rechts |
Kleiner als x < y |
|
|
Kleiner oder gleich x <= y |
|||
|
Größer als x > y |
|||
|
Größer oder gleich x >= y |
|||
| x in y | |||
| x instanceof y | |||
| 8: Gleichheitsoperatoren | von links nach rechts |
Gleichheit x == y |
|
|
Ungleichheit x != y |
|||
|
Strikte Gleichheit x === y |
|||
|
Strikte Ungleichheit x !== y |
|||
| 7: Bitweises UND | von links nach rechts |
Bitweises UND x & y |
|
| 6: Bitweises XOR | von links nach rechts |
Bitweises XOR x ^ y |
|
| 5: Bitweises ODER | von links nach rechts |
Bitweises ODER x | y |
|
| 4: Logisches UND | von links nach rechts |
Logisches UND x && y |
|
| 3: Logisches ODER, Nullish Coalescing | von links nach rechts |
Logisches ODER x || y |
|
|
Nullish Coalescing Operator x ?? y |
[9] | ||
| 2: Zuweisung und Sonstiges | von rechts nach links |
Zuweisung x = y |
[10] |
|
Addition-Zuweisung x += y |
|||
|
Subtraktion-Zuweisung x -= y |
|||
|
Exponentiation-Zuweisung x **= y |
|||
|
Multiplikation-Zuweisung x *= y |
|||
|
Division-Zuweisung x /= y |
|||
|
Rest-Zuweisung x %= y |
|||
|
Linksschiebe-Zuweisung x <<= y |
|||
|
Rechtsschiebe-Zuweisung x >>= y |
|||
|
Unsigned-Rechtsschiebe-Zuweisung x >>>= y |
|||
|
Bitweises UND-Zuweisung x &= y |
|||
|
Bitweises XOR-Zuweisung x ^= y |
|||
|
Bitweises ODER-Zuweisung x |= y |
|||
|
Logisches UND-Zuweisung x &&= y |
|||
|
Logisches ODER-Zuweisung x ||= y |
|||
|
Nullish Coalescing-Zuweisung x ??= y |
|||
| von rechts nach links |
Bedingter (ternärer) Operator x ? y : z |
[11] | |
| von rechts nach links |
Pfeil x => y |
[12] | |
| n/a | yield x | ||
| yield* x | |||
|
Spread ...x |
[13] | ||
| 1: Komma | von links nach rechts |
Komma-Operator x, y |
Hinweise:
Die Rangfolge der Gruppen 17 und 16 kann etwas mehrdeutig sein. Hier einige Beispiele zur Klärung:
Der Bauplan für ein besseres Internet.
Besuche die gemeinnützige Muttergesellschaft der Mozilla Corporation, die Mozilla Foundation.
Teile dieses Inhalts sind ©1998–2026 von einzelnen mozilla.org-Mitwirkenden. Inhalte sind verfügbar unter einer Creative-Commons-Lizenz.