JavaScript – Das Handbuch für die Praxis. David Flanagan

JavaScript  –  Das Handbuch für die Praxis - David Flanagan


Скачать книгу
Variablen oder einer Eigenschaft einen Wert zu, ändert das den Wert aller Ausdrücke, die diese Variable bzw. Eigenschaft benutzen. Die Inkrement- und Dekrementoperatoren ++ und -- verhalten sich ebenfalls so, da sie implizit eine Zuweisung durchführen. Auch der delete-Operator hat Seiteneffekte: Das Löschen einer Eigenschaft ähnelt der Zuweisung von undefined an diese Eigenschaft (ist aber nicht genau dasselbe).

      Die anderen JavaScript-Operatoren haben keine Seiteneffekte. Man sollte jedoch beachten, dass Ausdrücke zum Funktionsaufruf und zur Objekterstellung solche Effekte haben, wenn einer der im Funktionskörper oder Konstruktor genutzten Operatoren Seiteneffekte hat.

       4.7.4Vorrang von Operatoren

      Die in Tabelle 4-1 aufgeführten Operatoren sind nach absteigendem Vorrang, auch Präzedenz genannt, angeordnet, und zwischen den verschiedenen Vorrangstufen sind Trennlinien eingefügt. Der Operatorvorrang steuert, in welcher Abfolge Operationen ausgeführt werden. Operatoren mit höherem Vorrang (diejenigen, die weiter oben in der Tabelle stehen) werden vor denen mit niedrigerem Vorrang (denjenigen, die weiter unten in der Tabelle stehen) ausgeführt.

      Betrachten Sie den folgenden Ausdruck:

      w = x + y*z;

      Der Multiplikationsoperator * hat einen höheren Vorrang als der Additionsoperator +, die Multiplikation wird also vor der Addition ausgeführt (und hat damit auch umgangssprachlich »Vorrang«). Der Zuweisungsoperator = hat schließlich den geringsten Vorrang: Die Zuweisung wird also erst ausgeführt, nachdem alle Operationen auf der rechten Seite durchgeführt wurden.

      Der Operatorvorrang kann durch den expliziten Einsatz von Klammern überschrieben werden. Ändern Sie den Ausdruck folgendermaßen, wenn Sie erzwingen wollen, dass die Addition zuerst ausgeführt wird:

      w = (x + y)*z;

      Beachten Sie bitte, dass Eigenschaftszugriffs- und Aufrufausdrücke höheren Vorrang haben als alle in Tabelle 4-1 aufgeführten Operatoren. Betrachten Sie diesen Ausdruck:

      // my ist ein Objekt mit einer Eigenschaft namens functions, deren Wert ein

      // Array von Funktionen ist. Wir rufen die Funktion mit dem Index x auf,

      // übergeben ihr das Argument y und fragen dann nach dem Typ des zurückgegebenen

      // Werts.

      typeof my.functions[x](y)

      Obwohl typeof einer der Operatoren mit der höchsten Priorität ist, wird die entsprechende Operation auf dem Ergebnis von Eigenschaftszugriff, Array-Index und Funktionsaufruf ausgeführt, die alle eine höhere Priorität als Operatoren haben.

      Sollten Sie sich nicht sicher sein, welchen Vorrang die von Ihnen verwendeten Operatoren haben, ist es empfehlenswert, die Auswertung explizit durch die Einführung von Klammern zu steuern. Folgende Regeln sollten Sie sich auf alle Fälle merken: Multiplikation und Division werden vor Addition und Subtraktion ausgeführt; Zuweisungen haben sehr geringen Vorrang und werden fast immer zuletzt ausgeführt.

      Wenn neue Operatoren zu JavaScript hinzugefügt werden, passen sie nicht immer nahtlos in die vorhandene Vorrangordnung. Der ??-Operator (siehe 4.13.2) wird in der Tabelle mit niedrigerem Vorrang als || und && dargestellt, aber tatsächlich ist sein Vorrang relativ zu diesen Operatoren nicht definiert, und ES2020 verlangt die explizite Verwendung von Klammern, wenn man ?? zusammen mit || oder && einsetzen will. In ähnlicher Weise hat der neue Exponentialoperator ** keine genau definierte Präzedenz gegenüber dem unären Negationsoperator, und Sie müssen Klammern verwenden, wenn Sie die Negation mit der Potenzierung kombinieren.

       4.7.5Operatorassoziativität

      In Tabelle 4-1 gibt die Spalte »A« die Assoziativität des Operators an. Der Wert L besagt, dass der Operator linksassoziativ ist, der Wert R, dass er rechtsassoziativ ist. Die Assoziativität eines Operators definiert, in welcher Reihenfolge Operationen mit gleichem Vorrang ausgeführt werden. Linksassoziativität heißt, dass die Operationen von links nach rechts ausgeführt werden. Da der Subtraktionsoperator linksassoziativ ist, ist

      w = x - y - z;

      dasselbe wie:

      w = ((x - y) - z);

      Betrachten Sie andererseits die folgenden Ausdrücke:

      y = a ** b ** c;

      x = ~-y;

      w = x = y = z;

      q = a?b:c?d:e?f:g;

      Diese entsprechen:

      y = (a ** (b ** c));

      x = ~(-y);

      w = (x = (y = z));

      q = a?b:(c?d:(e?f:g));

      Warum? Weil die unären Operatoren, der Zuweisungs- und der Ternäroperator rechtsassoziativ sind und die entsprechenden Operationen von rechts nach links ausgeführt werden.

       4.7.6Reihenfolge der Auswertung

      Operatorvorrang und Assoziativität bedingen die Reihenfolge, in der die Operationen in einem komplexen Ausdruck ausgeführt werden. Sie legen jedoch nicht fest, in welcher Reihenfolge Unterausdrücke ausgewertet werden. Ausdrücke werden in JavaScript immer streng von links nach rechts evaluiert. In dem Ausdruck w = x + y * z wird z.B. zuerst der Unterausdruck w ausgewertet, gefolgt von x, y und z. Dann werden die Werte von y und z multipliziert, zum Wert von x addiert und der durch den Ausdruck w spezifizierten Variablen oder Eigenschaft zugewiesen. Fügt man Ausdrücken Klammern hinzu, lässt sich dadurch die relative Reihenfolge der Multiplikation, Addition und Zuweisung ändern, nicht aber die Auswertungsreihenfolge, die von links nach rechts stattfindet.

      Die Auswertungsreihenfolge wird nur dann relevant, wenn einer der ausgewerteten Ausdrücke Nebeneffekte hat, die den Wert eines anderen Ausdrucks betreffen. Inkrementiert der Ausdruck x eine Variable, die von Ausdruck z genutzt wird, wird der Umstand relevant, dass x vor z ausgewertet wird.

       4.8Arithmetische Ausdrücke

      Dieser Abschnitt behandelt die Operatoren, die arithmetische oder andere numerische Manipulationen ihrer Operanden durchführen. Die Multiplikations-, Divisions- und Subtraktionsoperatoren sind unkompliziert, und wir behandeln sie gleich zu Beginn. Der Additionsoperator erhält einen eigenen Unterabschnitt, weil er auch String-Verkettungen durchführen kann und einige ungewöhnliche Umwandlungsregeln aufweist. Die unären Operatoren und die bitweisen Operatoren werden ebenfalls in eigenen Unterabschnitten näher betrachtet.

      Die meisten arithmetischen Operatoren (mit Ausnahme der nachfolgend aufgeführten) können mit BigInt-Operanden (siehe 3.2.5) oder mit regulären Zahlen verwendet werden, solange Sie die beiden Typen nicht vermischen.

      Die elementaren Operatoren sind ** (Potenzierung), * (Multiplikation), / (Division), % (Modulo: Rest nach Division), + (Addition) und - (Subtraktion). Die anderen fünf elementaren Operatoren werten einfach ihre Operanden aus, wandeln die Werte bei Bedarf in Zahlen um und berechnen dann die Potenz, das Produkt, den Quotienten, den Rest oder die Differenz. Nicht numerische Operanden, die nicht in Zahlen umgewandelt werden können, werden in den NaN-Wert konvertiert (Not a Number – keine Zahl). Wenn einer der Operanden NaN ist (oder dazu umgewandelt wird), lautet das Ergebnis der Operation ebenfalls NaN.

      Der **-Operator hat Vorrang vor *, / und % (die wiederum Vorrang haben vor + und -). Im Gegensatz


Скачать книгу