Ausdrücke und Operatoren
Dieses Kapitel beschreibt die Ausdrücke und Operatoren von JavaScript, einschließlich Zuweisung, Vergleich, Arithmetik, Bitweise, Logik, String, ternärer Operator und mehr.
Auf einem hohen Level ist ein Ausdruck eine gültige Codeeinheit, die zu einem Wert aufgelöst wird. Es gibt zwei Arten von Ausdrücken: solche, die Nebenwirkungen haben (wie das Zuweisen von Werten), und solche, die rein auswerten.
Der Ausdruck x = 7
ist ein Beispiel für die erste Art. Dieser Ausdruck verwendet den =
- Operator, um den Wert sieben der Variablen x
zuzuweisen. Der Ausdruck selbst wertet zu 7
aus.
Der Ausdruck 3 + 4
ist ein Beispiel für die zweite Art. Dieser Ausdruck verwendet den +
-Operator, um 3
und 4
zusammenzuzählen und ergibt einen Wert, 7
. Wenn er allerdings nicht Teil eines größeren Konstrukts ist (beispielsweise einer Variablendeklaration wie const z = 3 + 4
), wird sein Ergebnis sofort verworfen — das ist normalerweise ein Programmierfehler, weil die Auswertung keine Effekte erzeugt.
Wie die obigen Beispiele ebenfalls zeigen, werden alle komplexen Ausdrücke durch Operatoren verbunden, wie =
und +
. In diesem Abschnitt werden wir die folgenden Operatoren vorstellen:
- Zuweisungsoperatoren
- Vergleichsoperatoren
- Arithmetische Operatoren
- Bitweise Operatoren
- Logische Operatoren
- BigInt Operatoren
- String-Operatoren
- Bedingungs- (ternärer) Operator
- Komma-Operator
- Unäre Operatoren
- Relationsoperatoren
Diese Operatoren verbinden Operanden, die entweder durch höherwertige Operatoren oder einen der grundlegenden Ausdrücke gebildet werden. Eine vollständige und detaillierte Liste der Operatoren und Ausdrücke ist auch in der Referenz verfügbar.
Die Priorität der Operatoren bestimmt die Reihenfolge, in der sie bei der Auswertung eines Ausdrucks angewendet werden. Zum Beispiel:
const x = 1 + 2 * 3;
const y = 2 * 3 + 1;
Obwohl *
und +
in unterschiedlicher Reihenfolge erscheinen, würden beide Ausdrücke zu 7
führen, weil *
Vorrang vor +
hat, sodass der *
-verbundene Ausdruck immer zuerst ausgewertet wird. Sie können die Priorität der Operatoren durch die Verwendung von Klammern überschreiben (die einen gruppierten Ausdruck erzeugen — den grundlegenden Ausdruck). Eine komplette Tabelle der Operatorenpriorität sowie verschiedene Vorbehalte finden Sie auf der Seite Operator Precedence Reference.
JavaScript hat sowohl binäre als auch unäre Operatoren, und einen speziellen ternären Operator, den bedingten Operator. Ein binärer Operator erfordert zwei Operanden, einen vor dem Operator und einen nach dem Operator:
operand1 operator operand2
Zum Beispiel 3 + 4
oder x * y
. Diese Form wird als infix binärer Operator bezeichnet, weil der Operator zwischen zwei Operanden platziert ist. Alle binären Operatoren in JavaScript sind infix.
Ein unärer Operator erfordert einen einzigen Operanden, entweder vor oder nach dem Operator:
operator operand operand operator
Zum Beispiel x++
oder ++x
. Die Form operator operand
wird als prefix unärer Operator bezeichnet, und die Form operand operator
als postfix unärer Operator. ++
und --
sind die einzigen Postfix-Operatoren in JavaScript — alle anderen Operatoren, wie !
, typeof
, etc., sind Präfix.
Zuweisungsoperatoren
Ein Zuweisungsoperator weist seinem linken Operand basierend auf dem Wert seines rechten Operanden einen Wert zu.
Der einfache Zuweisungsoperator ist gleich (=
), der den Wert seines rechten Operanden seinem linken Operanden zuweist.
Das heißt, x = f()
ist ein Zuweisungsausdruck, der den Wert von f()
x
zuweist.
Es gibt auch zusammengesetzte Zuweisungsoperatoren, die eine Kurzfassung für die in der folgenden Tabelle aufgelisteten Operationen sind:
Name | Kurzoperator | Bedeutung |
---|---|---|
Zuweisung | x = f() |
x = f() |
Addition zuweisen | x += f() |
x = x + f() |
Subtraktion zuweisen | x -= f() |
x = x - f() |
Multiplikation zuweisen | x *= f() |
x = x * f() |
Division zuweisen | x /= f() |
x = x / f() |
Rest zuweisen | x %= f() |
x = x % f() |
Exponentiation zuweisen | x **= f() |
x = x ** f() |
Linksverschiebung zuweisen | x <<= f() |
x = x << f() |
Rechtsverschiebung zuweisen | x >>= f() |
x = x >> f() |
Unsigned-Rechtsverschiebung zuweisen | x >>>= f() |
x = x >>> f() |
Bitweises UND zuweisen | x &= f() |
x = x & f() |
Bitweises XOR zuweisen | x ^= f() |
x = x ^ f() |
Bitweises ODER zuweisen | x |= f() |
x = x | f() |
Logisches UND zuweisen | x &&= f() |
x && (x = f()) |
Logisches ODER zuweisen | x ||= f() |
x || (x = f()) |
Null-Koaleszenz zuweisen | x ??= f() |
x ?? (x = f()) |
Zuweisung an Eigenschaften
Wenn ein Ausdruck zu einem Objekt ausgewertet wird, kann die linke Seite eines Zuweisungsausdrucks Zuweisungen an Eigenschaften dieses Ausdrucks vornehmen. Beispielsweise:
const obj = {};
obj.x = 3;
console.log(obj.x); // Prints 3.
console.log(obj); // Prints { x: 3 }.
const key = "y";
obj[key] = 5;
console.log(obj[key]); // Prints 5.
console.log(obj); // Prints { x: 3, y: 5 }.
Für weitere Informationen über Objekte lesen Sie Arbeiten mit Objekten.
Wenn ein Ausdruck nicht zu einem Objekt ausgewertet wird, dann führen Zuweisungen an Eigenschaften dieses Ausdrucks zu keinen Zuweisungen:
const val = 0;
val.x = 3;
console.log(val.x); // Prints undefined.
console.log(val); // Prints 0.
Im Strict-Mode wirft der obige Code einen Fehler, weil man keinen Eigenschaften von Primitiven zuweisen kann.
Es ist ein Fehler, Werte an unveränderbare Eigenschaften oder an Eigenschaften eines Ausdrucks ohne Eigenschaften (null
oder undefined
) zuzuweisen.
Destrukturierung
Für komplexere Zuweisungen ist die Destrukturierungs-Syntax ein JavaScript-Ausdruck, der es ermöglicht, Daten aus Arrays oder Objekten mithilfe einer Syntax zu extrahieren, die den Konstruktionen von Array- und Objekt-Literalen ähnelt.
Ohne Destrukturierung erfordert es mehrere Anweisungen, um Werte aus Arrays und Objekten zu extrahieren:
const foo = ["one", "two", "three"];
const one = foo[0];
const two = foo[1];
const three = foo[2];
Mit Destrukturierung können Sie mehrere Werte in getrennte Variablen mit nur einer Anweisung extrahieren:
const [one, two, three] = foo;
Auswertung und Verschachtelung
Im Allgemeinen werden Zuweisungen innerhalb einer Variablendeklaration (d.h. mit const
, let
oder var
) oder als eigenständige Anweisungen verwendet.
// Declares a variable x and initializes it to the result of f().
// The result of the x = f() assignment expression is discarded.
let x = f();
x = g(); // Reassigns the variable x to the result of g().
Jedoch, wie bei anderen Ausdrücken, werten Zuweisungsausdrücke wie x = f()
zu einem Ergebniswert aus.
Obwohl dieser Ergebniswert üblicherweise nicht verwendet wird, kann er anschließend von einem anderen Ausdruck verwendet werden.
Das Verketteten von Zuweisungen oder das Verschachteln von Zuweisungen in andere Ausdrücke kann zu überraschendem Verhalten führen. Aus diesem Grund raten einige JavaScript-Stilrichtlinien davon ab, Zuweisungen zu verketten oder zu verschachteln. Dennoch können Zuweisungsverketten und -verschachteln manchmal vorkommen, daher ist es wichtig, zu verstehen, wie sie funktionieren.
Indem ein Zuweisungsausdruck verkettet oder verschachtelt wird, kann sein Ergebnis selbst einer anderen Variablen zugewiesen werden. Es kann protokolliert oder in einem Array-Literal oder Funktionsaufruf eingefügt werden, und so weiter.
let x;
const y = (x = f()); // Or equivalently: const y = x = f();
console.log(y); // Logs the return value of the assignment x = f().
console.log(x = f()); // Logs the return value directly.
// An assignment expression can be nested in any place
// where expressions are generally allowed,
// such as array literals' elements or as function calls' arguments.
console.log([0, x = f(), 0]);
console.log(f(0, x = f(), 0));
Das Auswertungsergebnis entspricht dem Ausdruck rechts vom =
Zeichen in der
"Bedeutung"-Spalte der Tabelle oben. Das bedeutet, dass x = f()
in
was auch immer f()
's Ergebnis ist, auswertet, x += f()
in die resultierende Summe x + f()
,
x **= f()
in die resultierende Potenz x ** f()
, und so weiter.
Im Fall von logischen Zuweisungen, x &&= f()
,
x ||= f()
, und x ??= f()
, ist der Rückgabewert der der
logischen Operation ohne Zuweisung, also x && f()
,
x || f()
, und x ?? f()
, jeweils.
Beim Verketteten dieser Ausdrücke ohne Klammern oder andere Gruppierungsoperatoren wie Array-Literalen, werden die Zuweisungsausdrücke rechts nach links gruppiert (sie sind rechtsassoziativ), aber sie werden links nach rechts ausgewertet.
Beachten Sie, dass bei allen Zuweisungsoperatoren außer =
selbst,
die resultierenden Werte immer auf den Werten der Operanden vor
der Operation basieren.
Zum Beispiel, nehmen wir an, dass folgende Funktionen f
und g
und die Variablen x
und y
deklariert wurden:
function f() {
console.log("F!");
return 2;
}
function g() {
console.log("G!");
return 3;
}
let x, y;
Betrachten wir diese drei Beispiele:
y = x = f();
y = [f(), x = g()];
x[f()] = g();
Auswertungsbeispiel 1
y = x = f()
ist gleichwertig mit y = (x = f())
,
weil der Zuweisungsoperator =
rechtsassoziativ ist.
Er wird jedoch von links nach rechts ausgewertet:
- Der Zuweisungsausdruck
y = x = f()
beginnt mit der Auswertung.- Das
y
auf der linken Seite dieser Zuweisung wertet in eine Referenz auf die Variable genannty
aus. - Der Zuweisungsausdruck
x = f()
beginnt mit der Auswertung.- Das
x
auf der linken Seite dieser Zuweisung wertet in eine Referenz auf die Variable genanntx
aus. - Der Funktionsaufruf
f()
gibt "F!" in der Konsole aus und wertet dann zur Zahl2
aus. - Dieses
2
-Ergebnis vonf()
wirdx
zugewiesen.
- Das
- Der Zuweisungsausdruck
x = f()
hat jetzt die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vonx
, nämlich2
. - Dieses
2
-Ergebnis wird wiederum auchy
zugewiesen.
- Das
- Der Zuweisungsausdruck
y = x = f()
hat jetzt die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vony
— der zufällig2
ist.x
undy
sind auf2
zugewiesen, und die Konsole hat "F!" ausgegeben.
Auswertungsbeispiel 2
y = [ f(), x = g() ]
wird ebenfalls von links nach rechts ausgewertet:
- Der Zuweisungsausdruck
y = [ f(), x = g() ]
beginnt mit der Auswertung.- Das
y
auf der linken Seite dieser Zuweisung wertet in eine Referenz auf die Variable genannty
aus. - Das innere Array-Literal
[ f(), x = g() ]
beginnt mit der Auswertung.- Der Funktionsaufruf
f()
gibt "F!" in der Konsole aus und wertet dann zur Zahl2
aus. - Der Zuweisungsausdruck
x = g()
beginnt mit der Auswertung.- Das
x
auf der linken Seite dieser Zuweisung wertet in eine Referenz auf die Variable genanntx
aus. - Der Funktionsaufruf
g()
gibt "G!" in der Konsole aus und wertet dann zur Zahl3
aus. - Dieses
3
-Ergebnis vong()
wirdx
zugewiesen.
- Das
- Der Zuweisungsausdruck
x = g()
hat jetzt die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vonx
, welcher3
ist. Dieses3
-Ergebnis wird zum nächsten Element im inneren Array-Literal (nach dem2
vonf()
).
- Der Funktionsaufruf
- Das innere Array-Literal
[ f(), x = g() ]
hat jetzt die Auswertung abgeschlossen; sein Ergebnis ist ein Array mit zwei Werten:[ 2, 3 ]
. - Dieses
[ 2, 3 ]
Array wird jetzty
zugewiesen.
- Das
- Der Zuweisungsausdruck
y = [ f(), x = g() ]
hat jetzt die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vony
– welcher zufällig[ 2, 3 ]
ist.x
ist jetzt auf3
zugewiesen,y
ist jetzt auf[ 2, 3 ]
zugewiesen, und die Konsole hat "F!" und dann "G!" ausgegeben.
Auswertungsbeispiel 3
x[f()] = g()
wird ebenfalls von links nach rechts ausgewertet.
(Dieses Beispiel setzt voraus, dass x
bereits einem Objekt zugewiesen ist.
Für weitere Informationen über Objekte lesen Sie Arbeiten mit Objekten.)
- Der Zuweisungsausdruck
x[f()] = g()
beginnt mit der Auswertung.- Der
x[f()]
-Eigenschaften Zugriff auf der linken Seite dieser Zuweisung beginnt mit der Auswertung.- Das
x
in diesem Zugriff wertet in eine Referenz auf die Variable genanntx
aus. - Dann gibt der Funktionsaufruf
f()
"F!" in der Konsole aus und wertet dann zur Zahl2
aus.
- Das
- Der
x[f()]
-Eigenschaften Zugriff auf dieser Zuweisung hat jetzt die Auswertung abgeschlossen; sein Ergebnis ist eine variable Eigenschaftenreferenz:x[2]
. - Dann gibt der Funktionsaufruf
g()
"G!" in der Konsole aus und wertet dann zur Zahl3
aus. - Dieses
3
wird jetztx[2]
zugewiesen. (Dieser Schritt wird nur dann erfolgreich sein, wennx
einem Objekt zugewiesen ist.)
- Der
- Der Zuweisungsausdruck
x[f()] = g()
hat jetzt die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vonx[2]
– der zufällig3
ist.x[2]
ist jetzt auf3
zugewiesen, und die Konsole hat "F!" und dann "G!" ausgegeben.
Verwenden Sie keine Zuweisungsketten
Das Verkettete von Zuweisungen oder das Verschachteln von Zuweisungen in andere Ausdrücke kann zu überraschendem Verhalten führen. Aus diesem Grund wird das Verkettete von Zuweisungen in derselben Anweisung nicht empfohlen.
Insbesondere das Platzieren einer Variablendevikette in einer const
, let
oder var
Anweisung funktioniert oft nicht. Nur die äußerste/linkeste Variable wird deklariert; andere Variablen innerhalb der Zuweisungskette werden nicht durch die const
/let
/var
-Anweisung deklariert.
Zum Beispiel:
const z = y = x = f();
Diese Anweisung deklariert scheinbar die Variablen x
, y
und z
.
Sie deklariert jedoch tatsächlich nur die Variable z
.
y
und x
sind entweder ungültige Referenzen auf nicht vorhandene Variablen (im Strict-Mode) oder, schlimmer noch, würden implizit globale Variablen für x
und y
im lockerem Modus erstellen.
Vergleichsoperatoren
Ein Vergleichsoperator vergleicht seine Operanden und gibt einen logischen Wert basierend darauf zurück, ob der Vergleich wahr ist.
Die Operanden können numerische, stringische, logische oder objektbasierte Werte sein.
Zeichenketten werden basierend auf der standardmäßigen lexikographischen Reihenfolge unter Verwendung von Unicode-Werten verglichen.
In den meisten Fällen, wenn die beiden Operanden nicht vom gleichen Typ sind, versucht JavaScript sie in einen angemessenen Typ für den Vergleich zu konvertieren.
Dieses Verhalten führt im Allgemeinen dazu, dass die Operanden numerisch verglichen werden.
Die einzigen Ausnahmen von der Konvertierung von Typen innerhalb von Vergleichen betreffen die ===
und !==
Operatoren, die strikte Gleichheits- bzw. Ungleichheitsvergleiche durchführen.
Diese Operatoren versuchen nicht, die Operanden in kompatible Typen zu konvertieren, bevor sie die Gleichheit überprüfen.
Die folgende Tabelle beschreibt die Vergleichsoperatoren anhand dieses Beispielcodes:
const var1 = 3;
const var2 = 4;
Operator | Beschreibung | Beispiele, die true zurückgeben |
---|---|---|
Gleich (== )
|
Gibt true zurück, wenn die Operanden gleich sind. |
3 == var1
3 == '3'
|
Nicht gleich (!= )
|
Gibt true zurück, wenn die Operanden nicht gleich sind. |
var1 != 4
|
Strikte Gleichheit (=== )
|
Gibt true zurück, wenn die Operanden gleich und vom gleichen
Typ sind. Siehe auch Object.is und
Gleichheit in JS.
|
3 === var1 |
Strikte Ungleichheit (!== )
|
Gibt true zurück, wenn die Operanden vom gleichen Typ, aber nicht gleich oder von einem unterschiedlichen Typ sind.
|
var1 !== "3"
|
Größer als (> )
|
Gibt true zurück, wenn der linke Operand größer als der rechte Operand ist.
|
var2 > var1
|
Größer oder gleich
(>= )
|
Gibt true zurück, wenn der linke Operand größer oder gleich dem rechten Operand ist.
|
var2 >= var1
|
Kleiner als
(< )
|
Gibt true zurück, wenn der linke Operand kleiner als der rechte Operand ist.
|
var1 < var2
|
Kleiner oder gleich
(<= )
|
Gibt true zurück, wenn der linke Operand kleiner oder gleich dem rechten Operand ist.
|
var1 <= var2
|
Hinweis: =>
ist kein Vergleichsoperator, sondern die Notation
für Arrow-Funktionen.
Arithmetische Operatoren
Ein arithmetischer Operator nimmt numerische Werte (entweder Literale oder Variablen) als ihre Operanden und gibt einen einzelnen numerischen Wert zurück.
Die Standardarithmetik-Operatoren sind Addition (+
), Subtraktion (-
), Multiplikation (*
) und Division (/
).
Diese Operatoren funktionieren wie in den meisten anderen Programmiersprachen, wenn sie mit Gleitkommazahlen verwendet werden (insbesondere beachten Sie, dass die Division durch Null Infinity
produziert). Zum Beispiel:
1 / 2; // 0.5
1 / 2 === 1.0 / 2.0; // this is true
Zusätzlich zu den Standardarithmetikoperationen (+
, -
, *
, /
) bietet JavaScript die in der folgenden Tabelle aufgelisteten arithmetischen Operatoren:
Operator | Beschreibung | Beispiel |
---|---|---|
Rest (% )
|
Binärer Operator. Gibt den ganzzahligen Rest der Division der beiden Operanden zurück. | 12 % 5 ergibt 2. |
Inkrement (++ )
|
Unärer Operator. Addiert eins zu seinem Operanden. Wenn als Präfix-Operator verwendet
(++x ), gibt er den Wert seines Operanden nach dem Hinzufügen von eins zurück;
wenn er als Postfix-Operator verwendet wird (x++ ), gibt er den Wert
seines Operanden vor dem Hinzufügen von eins zurück.
|
Wenn x 3 ist, dann setzt ++x x auf 4
und gibt 4 zurück, während x++ 3 zurückgibt und erst danach x auf 4 setzt.
|
Dekrement (-- )
|
Unärer Operator. Subtrahiert eins von seinem Operanden. Der Rückgabewert ist analog zu dem des Inkrement-Operators. |
Wenn x 3 ist, dann setzt --x x auf 2
und gibt 2 zurück, während x-- 3 zurückgibt und erst danach x auf 2 setzt.
|
Unäre Negation (- )
|
Unärer Operator. Gibt die Negation seines Operanden zurück. | Wenn x 3 ist, dann gibt -x -3 zurück. |
Unäres Plus (+ )
|
Unärer Operator. Versucht, den Operanden in eine Zahl zu konvertieren, falls er es nicht bereits ist. |
|
Exponentiation-Operator (** )
|
Berechnet die basis zur exponent -Potenz,
das heißt, basis^exponent
|
2 ** 3 gibt 8 zurück.10 ** -1
gibt 0.1 zurück.
|
Bitweise Operatoren
Ein bitweiser Operator behandelt seine Operanden als eine Menge von 32 Bits (Nullen und Einsen), anstatt als Dezimal-, Hexadezimal- oder Oktalzahlen. Zum Beispiel hat die Dezimalzahl neun eine Binärdarstellung von 1001. Bitweise Operatoren führen ihre Operationen auf solchen Binärdarstellungen aus, geben jedoch Standard-JavaScript-Zahlenwerte zurück.
Die folgende Tabelle fasst die bitweisen Operatoren in JavaScript zusammen.
Operator | Verwendung | Beschreibung |
---|---|---|
Bitweises UND | a & b |
Gibt eine eins in jeder Bitposition zurück, für die die entsprechenden Bits beider Operanden eins sind. |
Bitweises ODER | a | b |
Gibt eine null in jeder Bitposition zurück, für die die entsprechenden Bits beider Operanden null sind. |
Bitweises XOR | a ^ b |
Gibt eine null in jeder Bitposition zurück, für die die entsprechenden Bits gleich sind. [Gibt eine eins in jeder Bitposition zurück, für die die entsprechenden Bits unterschiedlich sind.] |
Bitweises NICHT | ~ a |
Invertiert die Bits seines Operanden. |
Linksverschiebung | a << b |
Verschiebt a in binärer Darstellung b Bits nach links und schiebt Nullen von rechts ein. |
Zeichenvorschub-Rechtsverschiebung | a >> b |
Verschiebt a in binärer Darstellung b Bits nach rechts, verwirft Bits, die verschoben wurden. |
Nullen auffüllende Rechtsverschiebung | a >>> b |
Verschiebt a in binärer Darstellung b Bits nach rechts, verwirft Bits, die verschoben wurden, und schiebt Nullen von links ein. |
Bitweise logische Operatoren
Konzepteurlich arbeiten die bitweisen logischen Operatoren wie folgt:
-
Die Operanden werden in Zweiunddreißig-Bit-Ganzzahlen konvertiert und durch eine Serie von Bits (Nullen und Einsen) ausgedrückt. Zahlen mit mehr als 32 Bits haben ihre signifikantesten Bits verworfen. Zum Beispiel wird die folgende Ganzzahl mit mehr als 32 Bits in eine 32-Bit-Ganzzahl konvertiert:
Before: 1110 0110 1111 1010 0000 0000 0000 0110 0000 0000 0001 After: 1010 0000 0000 0000 0110 0000 0000 0001
-
Jedes Bit im ersten Operanden wird mit dem entsprechenden Bit im zweiten Operanden gepaart: erstes Bit zu erstem Bit, zweites Bit zu zweitem Bit, und so weiter.
-
Der Operator wird auf jedes Bitpaar angewendet, und das Ergebnis wird bitweise konstruiert.
Zum Beispiel ist die Binärdarstellung von neun 1001, und die Binärdarstellung von fünfzehn ist 1111. Also sind, wenn die bitweisen Operatoren auf diese Werte angewendet werden, die Ergebnisse wie folgt:
Ausdruck | Ergebnis | Beschreibungen in Binärform |
---|---|---|
15 & 9 |
9 |
1111 & 1001 = 1001 |
15 | 9 |
15 |
1111 | 1001 = 1111 |
15 ^ 9 |
6 |
1111 ^ 1001 = 0110 |
~15 |
-16 |
~ 0000 0000 ... 0000 1111 = 1111 1111 ... 1111 0000 |
~9 |
-10 |
~ 0000 0000 ... 0000 1001 = 1111 1111 ... 1111 0110 |
Beachten Sie, dass alle 32 Bits mit dem Bitweisen NICHT-Operator invertiert werden und dass Werte mit dem am meisten signifikanten (linkesten) Bit, das auf 1 gesetzt ist, negative Zahlen darstellen (Zwei's-Komplement-Darstellung). ~x
wertet auf denselben Wert aus, den -x - 1
ergibt.
Bitweise Verschiebeoperatoren
Die bitweisen Verschiebeoperatoren benötigen zwei Operanden: der erste ist eine Menge, die verschoben wird, und der zweite gibt die Anzahl der Bitpositionen an, um die der erste Operand verschoben werden soll. Die Richtung der Verschiebeoperation wird durch den verwendeten Operator gesteuert.
Verschiebeoperatoren konvertieren ihre Operanden in zweiunddreißig-bitige Ganzzahlen und geben ein Ergebnis des Typs Number
oder BigInt
zurück: Insbesondere, wenn der Typ des linken Operanden BigInt
ist, geben sie BigInt
zurück; andernfalls geben sie Number
zurück.
Die Verschiebeoperatoren sind in der folgenden Tabelle aufgelistet.
Operator | Beschreibung | Beispiel |
---|---|---|
Linksverschiebung ( << )
|
Dieser Operator verschiebt den ersten Operanden die angegebene Anzahl von Bits nach links. Überzählige Bits, die nach links verschoben werden, werden verworfen. Null-Bits werden von rechts eingefügt. |
9<<2 ergibt 36, weil 1001 um 2 Bits nach links verschoben 100100 ergibt, was 36 ist.
|
Zeichenvorschub-Rechtsverschiebung (>> )
|
Dieser Operator verschiebt den ersten Operanden die angegebene Anzahl von Bits nach rechts. Überzählige Bits, die nach rechts verschoben werden, werden verworfen. Kopien des linken Bits werden von links eingefügt. |
9>>2 ergibt 2, weil 1001 um 2 Bits nach rechts verschoben 10 ergibt, was 2 ist. Ebenso ergibt -9>>2 -3, weil das Vorzeichen erhalten bleibt.
|
Nullen auffüllende Rechtsverschiebung (>>> )
|
Dieser Operator verschiebt den ersten Operanden die angegebene Anzahl von Bits nach rechts. Überzählige Bits, die nach rechts verschoben werden, werden verworfen. Null-Bits werden von links eingefügt. |
19>>>2 ergibt 4, weil 10011 um 2 Bits nach rechts verschoben 100 ergibt, was 4 ist. Bei nicht-negativen Zahlen ergeben Nullen auffüllende Rechtsverschiebung und zeichenvorschub-Rechtsverschiebung dasselbe Ergebnis.
|
Logische Operatoren
Logische Operatoren werden typischerweise mit booleschen (logischen) Werten verwendet; wenn sie es sind, geben sie einen booleschen Wert zurück.
Jedoch geben die Operatoren &&
, ||
und ??
tatsächlich den Wert eines der angegebenen Operanden zurück, sodass wenn diese Operatoren mit nicht-boolschen Werten verwendet werden, sie einen nicht-booleschen Wert zurückgeben können. Daher werden sie besser als "Wertauswahloperatoren" bezeichnet.
Die logischen Operatoren sind in der folgenden Tabelle beschrieben.
Operator | Verwendung | Beschreibung |
---|---|---|
Logisches UND (&& )
|
expr1 && expr2 |
Gibt expr1 zurück, wenn es in false konvertiert werden kann;
andernfalls gibt es expr2 zurück. So gibt && bei Verwendung mit booleschen
Werten true zurück, wenn beide Operanden wahr sind; andernfalls gibt es false zurück.
|
Logisches ODER (|| )
|
expr1 || expr2 |
Gibt expr1 zurück, wenn es in true konvertiert werden kann;
andernfalls gibt es expr2 zurück. So gibt || bei Verwendung mit booleschen
Werten true zurück, wenn entweder Operand wahr ist; wenn beide falsch sind, gibt es false zurück.
|
Null-Koaleszenzoperator (?? )
|
expr1 ?? expr2 |
Gibt expr1 zurück, wenn es weder null noch
undefined ist; andernfalls gibt es expr2 zurück.
|
Logisches NICHT (! )
|
!expr |
Gibt false zurück, wenn sein einzelner Operand in
true konvertiert werden kann; andernfalls gibt es true zurück.
|
Beispiele für Ausdrücke, die in false
konvertiert werden können, sind solche, die zu null
, 0
, 0n
, NaN
, dem leeren String (""
) oder undefined
ausgewertet werden.
Der folgende Code zeigt Beispiele für den &&
(logisches UND) Operator.
const a1 = true && true; // t && t returns true
const a2 = true && false; // t && f returns false
const a3 = false && true; // f && t returns false
const a4 = false && 3 === 4; // f && f returns false
const a5 = "Cat" && "Dog"; // t && t returns Dog
const a6 = false && "Cat"; // f && t returns false
const a7 = "Cat" && false; // t && f returns false
Der folgende Code zeigt Beispiele für den ||
(logisches ODER) Operator.
const o1 = true || true; // t || t returns true
const o2 = false || true; // f || t returns true
const o3 = true || false; // t || f returns true
const o4 = false || 3 === 4; // f || f returns false
const o5 = "Cat" || "Dog"; // t || t returns Cat
const o6 = false || "Cat"; // f || t returns Cat
const o7 = "Cat" || false; // t || f returns Cat
Der folgende Code zeigt Beispiele für den ??
(Null-Koaleszenz) Operator.
const n1 = null ?? 1; // 1
const n2 = undefined ?? 2; // 2
const n3 = false ?? 3; // false
const n4 = 0 ?? 4; // 0
Beachten Sie, wie ??
wie ||
funktioniert, aber es gibt nur den zweiten Ausdruck zurück, wenn der erste "nullish" ist, d.h. null
oder undefined
. ??
ist eine bessere Alternative als ||
zum Setzen von Standards für Werte, die null
oder undefined
sein könnten, insbesondere wenn Werte wie ''
oder 0
gültige Werte sind und der Standard nicht angewendet werden sollte.
Der folgende Code zeigt Beispiele für den !
(logisches NICHT) Operator.
const n1 = !true; // !t returns false
const n2 = !false; // !f returns true
const n3 = !"Cat"; // !t returns false
Kurzschlussauswertung
Wenn logische Ausdrücke von links nach rechts ausgewertet werden, werden sie auf mögliche "Kurzschluss"-Auswertungen unter Verwendung der folgenden Regeln getestet:
falsy && irgendetwas
wird kurzgeschlossen zum falsy Wert ausgewertet.truthy || irgendetwas
wird kurzgeschlossen zum truthy Wert ausgewertet.nonNullish ?? irgendetwas
wird kurzgeschlossen zum non-nullish Wert ausgewertet.
Die Regeln der Logik garantieren, dass diese Auswertungen immer korrekt sind. Beachten Sie, dass der irgendetwas Teil der obigen Ausdrücke nicht ausgewertet wird, sodass keine Seiteneffekte dabei stattfinden.
BigInt Operatoren
Die meisten Operatoren, die zwischen Zahlen verwendet werden können, können auch zwischen BigInt
Werten verwendet werden.
// BigInt addition
const a = 1n + 2n; // 3n
// Division with BigInts round towards zero
const b = 1n / 2n; // 0n
// Bitwise operations with BigInts do not truncate either side
const c = 40000000000000000n >> 2n; // 10000000000000000n
Eine Ausnahme ist der unsigned right shift (>>>
), der für BigInt-Werte nicht definiert ist. Dies liegt daran, dass ein BigInt keine feste Breite hat, daher hat es technisch gesehen kein "höchstes Bit".
const d = 8n >>> 2n; // TypeError: BigInts have no unsigned right shift, use >> instead
BigInts und Zahlen sind nicht gegenseitig ersetzbar — Sie können sie nicht in Berechnungen mischen.
const a = 1n + 2; // TypeError: Cannot mix BigInt and other types
Dies liegt daran, dass BigInt weder ein Teil- noch ein Obermenge von Zahlen ist. BigInts haben eine höhere Genauigkeit als Zahlen bei der Darstellung großer Ganzzahlen, können jedoch keine Dezimalstellen darstellen, sodass bei jeder Seite der impliziten Konvertierung eine Genauigkeit verloren gehen könnte. Verwenden Sie die explizite Konvertierung, um anzugeben, ob Sie wünschen, dass die Operation eine Zahlenoperation oder eine BigInt-Operation ist.
const a = Number(1n) + 2; // 3
const b = 1n + BigInt(2); // 3n
Sie können BigInts mit Zahlen vergleichen.
const a = 1n > 2; // false
const b = 3 > 2n; // true
String-Operatoren
Zusätzlich zu den Vergleichsoperatoren, die auf String-Werten verwendet werden können, verknüpft der Konkatenationsoperator (+
) zwei String-Werte miteinander und gibt einen anderen String zurück, der die Vereinigung der zwei Operand Strings ist.
Beispielsweise,
console.log("my " + "string"); // console logs the string "my string".
Der Kurzzuweisungsoperator +=
kann ebenfalls verwendet werden, um Strings zu konkateniert.
Beispielsweise,
let myString = "alpha";
myString += "bet"; // evaluates to "alphabet" and assigns this value to myString.
Bedingungs- (ternärer) Operator
Der bedingte Operator ist der einzige JavaScript-Operator, der drei Operanden benötigt. Der Operator kann einen von zwei Werten basierend auf einer Bedingung annehmen. Die Syntax ist:
condition ? val1 : val2
Wenn condition
wahr ist, hat der Operator den Wert von val1
.
Andernfalls hat er den Wert von val2
. Sie können den bedingten Operator überall verwenden, wo Sie einen Standard-Operator verwenden würden.
Beispielsweise,
const status = age >= 18 ? "adult" : "minor";
Diese Anweisung weist der Variablen status
den Wert "adult" zu, wenn
age
achtzehn oder mehr ist. Andernfalls weist sie status
den Wert "minor" zu.
Komma-Operator
Der Komma-Operator (,
)
wertet beide Operanden aus und gibt den Wert des letzten Operanden zurück.
Dieser Operator wird hauptsächlich innerhalb einer for
-Schleife verwendet, um mehrere Variablen jedes Mal, wenn die Schleife durchlaufen wird, zu aktualisieren.
Es gilt als schlechter Stil, ihn an anderen Stellen zu verwenden, wenn er nicht notwendig ist.
Oft können und sollten stattdessen zwei separate Anweisungen verwendet werden.
Beispielsweise, wenn a
ein 2-dimensionales Array mit 10 Elementen auf einer Seite ist, verwendet der folgende Code den Komma-Operator, um zwei Variablen auf einmal zu aktualisieren.
Der Code gibt die Werte der diagonalen Elemente im Array aus:
const x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const a = [x, x, x, x, x];
for (let i = 0, j = 9; i <= j; i++, j--) {
// ^
console.log(`a[${i}][${j}]= ${a[i][j]}`);
}
Unäre Operatoren
Eine unäre Operation ist eine Operation mit nur einem Operanden.
delete
Der delete
Operator löscht eine Eigenschaft eines Objekts.
Die Syntax ist:
delete object.property;
delete object[propertyKey];
delete objectName[index];
wobei object
der Name eines Objekts ist, property
eine existierende Eigenschaft und propertyKey
entweder ein String oder Symbol ist, das auf eine existierende Eigenschaft verweist.
Wenn der delete
Operator erfolgreich ist, entfernt er die Eigenschaft aus dem Objekt.
Ein Zugriff darauf danach gibt undefined
zurück.
Der delete
Operator gibt true
zurück, wenn die Operation möglich ist; er gibt false
zurück, wenn die Operation nicht möglich ist.
delete Math.PI; // returns false (cannot delete non-configurable properties)
const myObj = { h: 4 };
delete myObj.h; // returns true (can delete user-defined properties)
Löschen von Array-Elementen
Da Arrays nur Objekte sind, ist es technisch möglich, Elemente daraus zu löschen
.
Dies gilt jedoch als schlechte Praxis — versuchen Sie, es zu vermeiden.
Wenn Sie eine Array-Eigenschaft löschen, wird die Array-Länge nicht beeinflusst und andere Elemente werden nicht neu indiziert.
Um dieses Verhalten zu erreichen, ist es viel besser, das Element einfach mit dem Wert undefined
zu überschreiben.
Um das Array tatsächlich zu manipulieren, verwenden Sie die verschiedenen Array-Methoden wie splice
.
typeof
Der typeof
Operator gibt einen String zurück, der den Typ des unevaluierten Operanden angibt.
operand
ist der String, die Variable, das Schlüsselwort oder das Objekt, für die/den der Typ zurückgegeben werden soll.
Die Klammern sind optional.
Angenommen, Sie definieren die folgenden Variablen:
const myFun = () => 5 + 2;
const shape = "round";
const size = 1;
const foo = ["Apple", "Mango", "Orange"];
const today = new Date();
Der typeof
Operator gibt folgende Ergebnisse für diese Variablen zurück:
typeof myFun; // returns "function"
typeof shape; // returns "string"
typeof size; // returns "number"
typeof foo; // returns "object"
typeof today; // returns "object"
typeof doesntExist; // returns "undefined"
Für die Schlüsselwörter true
und null
, gibt der typeof
Operator die folgenden Ergebnisse zurück:
typeof true; // returns "boolean"
typeof null; // returns "object"
Für eine Zahl oder einen String, gibt der typeof
Operator die folgenden Ergebnisse zurück:
typeof 62; // returns "number"
typeof "Hello world"; // returns "string"
Für Eigenschaftswerte gibt der typeof
Operator den Typ des
von der Eigenschaft enthaltenen Wertes zurück:
typeof document.lastModified; // returns "string"
typeof window.length; // returns "number"
typeof Math.LN2; // returns "number"
Für Methoden und Funktionen, gibt der typeof
Operator Ergebnisse wie folgt zurück:
typeof blur; // returns "function"
typeof parseInt; // returns "function"
typeof shape.split; // returns "function"
Für vordefinierte Objekte gibt der typeof
Operator Ergebnisse wie folgt zurück:
typeof Date; // returns "function"
typeof Function; // returns "function"
typeof Math; // returns "object"
typeof Option; // returns "function"
typeof String; // returns "function"
void
Der void
Operator spezifiziert einen Ausdruck, der auszuwerten ist, ohne einen Wert zurückzugeben. expression
ist ein JavaScript-Ausdruck, der ausgewertet wird.
Die Klammern, die den Ausdruck umgeben, sind optional, aber es ist gutes Stil, sie zu verwenden, um Vorrangprobleme zu vermeiden.
Relationsoperatoren
Ein Relationsoperator vergleicht seine Operanden und gibt einen Booleschen Wert basierend darauf zurück, ob der Vergleich wahr ist.
in
Der in
Operator gibt true
zurück, wenn die angegebene Eigenschaft im angegebenen Objekt enthalten ist.
Die Syntax ist:
propNameOrNumber in objectName
wobei propNameOrNumber
ein String-Nummern- oder Symbole-Ausdruck ist, der einen Eigenschaftsnamen oder Array-Index darstellt, und objectName
der Name eines Objekts ist.
Die folgenden Beispiele zeigen einige Anwendungen des in
Operators.
// Arrays
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
0 in trees; // returns true
3 in trees; // returns true
6 in trees; // returns false
"bay" in trees; // returns false
// (you must specify the index number, not the value at that index)
"length" in trees; // returns true (length is an Array property)
// built-in objects
"PI" in Math; // returns true
const myString = new String("coral");
"length" in myString; // returns true
// Custom objects
const myCar = { make: "Honda", model: "Accord", year: 1998 };
"make" in myCar; // returns true
"model" in myCar; // returns true
instanceof
Der instanceof
Operator gibt true
zurück
wenn das angegebene Objekt von dem angegebenen Objekttyp ist. Die Syntax ist:
object instanceof objectType
wobei object
das Objekt ist, das gegen objectType
getestet werden soll, und objectType
ein Konstruktor ist, der einen Typ darstellt, wie Map
oder Array
.
Verwenden Sie instanceof
, wenn Sie den Typ eines Objekts zur Laufzeit bestätigen müssen.
Zum Beispiel, wenn Sie Ausnahmen abfangen, können Sie in verschiedene Ausnahmebehandlungs-Code schnittigen, je nach dem Typ der geworfenen Ausnahme.
Zum Beispiel verwendet der folgende Code instanceof
, um zu bestimmen, ob obj
ein Map
-Objekt ist. Da obj
ein Map
-Objekt ist, werden die Anweisungen im if
-Block ausgeführt.
const obj = new Map();
if (obj instanceof Map) {
// statements to execute
}
Grundlegende Ausdrücke
Alle Operatoren arbeiten schließlich auf einem oder mehreren grundlegenden Ausdrücken. Diese grundlegenden Ausdrücke umfassen Bezeichner und Literale, aber es gibt auch einige andere Arten. Sie werden unten kurz eingeführt, und ihre Semantik wird in den jeweiligen Referenzabschnitten im Detail beschrieben.
this
Das this
Schlüsselwort wird üblicherweise innerhalb einer Funktion genutzt. Im Allgemeinen, wenn die Funktion an ein Objekt als Methode angehängt ist, bezieht sich this
auf das Objekt, das die Methode aufgerufen hat. Es funktioniert wie ein versteckter Parameter, der an die Funktion übergeben wird. this
ist ein Ausdruck, der in ein Objekt auswertet, sodass Sie alle Objektoperationen verwenden können, die wir eingeführt haben.
this["propertyName"];
this.propertyName;
doSomething(this);
Zum Beispiel, nehmen wir an, eine Funktion ist wie folgt definiert:
function getFullName() {
return `${this.firstName} ${this.lastName}`;
}
Wir können diese Funktion nun an ein Objekt anhängen, und es wird die Eigenschaften dieses Objekts nutzen, wenn es aufgerufen wird:
const person1 = {
firstName: "Chris",
lastName: "Martin",
};
const person2 = {
firstName: "Chester",
lastName: "Bennington",
};
// Attach the same function
person1.getFullName = getFullName;
person2.getFullName = getFullName;
console.log(person1.getFullName()); // "Chris Martin"
console.log(person2.getFullName()); // "Chester Bennington"
Gruppierungsoperator
Der Gruppierungsoperator ( )
kontrolliert den Vorrang der Auswertung in
Ausdrücken. Zum Beispiel können Sie die Multiplikation und Division außer Kraft setzen, erst dann
Addition und Subtraktion, um die Addition als erste zu bewerten.
const a = 1;
const b = 2;
const c = 3;
// default precedence
a + b * c; // 7
// evaluated by default like this
a + (b * c); // 7
// now overriding precedence
// addition before multiplication
(a + b) * c; // 9
// which is equivalent to
a * c + b * c; // 9
Eigenschafts-Zugriff
Die Eigenschafts-Zugriff Syntax ruft Eigenschaftswerte von Objekten ab, indem entweder Punktnotation oder Klammernotation verwendet wird.
object.property;
object["property"];
Das Arbeiten mit Objekten guide geht näher auf Objekteigenschaften ein.
Optionales Chaining
Die optionale Chaining Syntax (?.
) führt die verkettete Operation auf einem Objekt aus, wenn es definiert und nicht-null
ist, und überspringt ansonsten die Operation und gibt undefined
zurück.
Dies ermöglicht Ihnen, auf einen Wert zu operieren, der möglicherweise null
oder undefined
ist, ohne dass ein TypeError
ausgelöst wird.
maybeObject?.property;
maybeObject?.[property];
maybeFunction?.();
new
Sie können den new
Operator verwenden, um eine Instanz eines benutzerdefinierten Objekttyps oder eines der eingebauten Objekttypen zu erstellen. Verwenden Sie new
wie folgt:
const objectName = new ObjectType(param1, param2, /* …, */ paramN);
super
Das super
Schlüsselwort wird verwendet, um Funktionen auf dem Elterobjekt eines Objekts aufzurufen.
Es ist nützlich, um mit Klassen den Elternkonstruktor aufzurufen, zum Beispiel.
super(args); // calls the parent constructor.
super.functionOnParent(args);