Ausdrücke und Operatoren
Dieses Kapitel beschreibt Ausdrücke und Operatoren in JavaScript, einschließlich Zuordnung, Vergleich, Arithmetik, Bitweise, Logik, Zeichenkette, ternärer Operator und mehr.
Auf einer hohen Ebene ist ein Ausdruck eine gültige Codeeinheit, die zu einem Wert aufgelöst wird. Es gibt zwei Arten von Ausdrücken: solche, die Nebeneffekte 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 den Wert 7
. Wenn er jedoch nicht Teil eines größeren Konstrukts (zum Beispiel einer Variablen-Deklaration wie const z = 3 + 4
) ist, wird sein Ergebnis sofort verworfen – dies ist in der Regel ein Programmierfehler, da die Auswertung keine Effekte erzeugt.
Wie die obigen Beispiele ebenfalls zeigen, sind alle komplexen Ausdrücke durch Operatoren verbunden, wie z.B. =
und +
. In diesem Abschnitt stellen wir die folgenden Operatoren vor:
- Zuweisungsoperatoren
- Vergleichsoperatoren
- Arithmetische Operatoren
- Bitweise Operatoren
- Logische Operatoren
- BigInt-Operatoren
- String-Operatoren
- Bedingungsoperator (ternär)
- Komma-Operator
- Unäre Operatoren
- Relationsoperatoren
Diese Operatoren verbinden Operanden, die entweder von Operatoren mit höherer Priorität gebildet werden oder von einem der grundlegenden Ausdrücke. Eine vollständige und detaillierte Liste von Operatoren und Ausdrücken ist auch in der Referenz verfügbar.
Der Vorrang von 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 7
ergeben, da *
Vorrang vor +
hat, sodass der durch *
verbundene Ausdruck immer zuerst ausgewertet wird. Sie können den Vorrang der Operatoren mit Hilfe von Klammern überschreiben (was einen gruppierten Ausdruck erstellt – den grundlegenden Ausdruck). Eine vollständige Tabelle des Operatorvorrangs sowie verschiedene Fallstricke finden Sie auf der Seite Operatorvorrang-Referenz.
JavaScript hat sowohl binäre und unäre Operatoren als auch einen speziellen ternären Operator, den bedingten Operator. Ein binärer Operator benötigt 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 wird. Alle binären Operatoren in JavaScript sind infix.
Ein unärer Operator benötigt einen einzelnen Operanden, entweder vor oder nach dem Operator:
operator operand operand operator
Zum Beispiel x++
oder ++x
. Die Form Operator Operand
wird als Präfix-Unär-Operator bezeichnet, und die Form Operand Operator
als Postfix-Unär-Operator. ++
und --
sind die einzigen Postfix-Operatoren in JavaScript — alle anderen Operatoren, wie !
, typeof
, etc. sind Präfix.
Zuweisungsoperatoren
Ein Zuweisungsoperator weist seinem linken Operanden basierend auf dem Wert seines rechten Operanden einen Wert zu.
Der einfache Zuweisungsoperator ist das Gleichheitszeichen (=
), das 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 Abkürzungen für die in der folgenden Tabelle aufgeführten Operationen sind:
Name | Kurzschreib-Operator | Bedeutung |
---|---|---|
Zuweisung | x = f() |
x = f() |
Additionszuweisung | x += f() |
x = x + f() |
Subtraktionszuweisung | x -= f() |
x = x - f() |
Multiplikationszuweisung | x *= f() |
x = x * f() |
Divisionszuweisung | x /= f() |
x = x / f() |
Restzuweisung | x %= f() |
x = x % f() |
Exponentialzuweisung | x **= f() |
x = x ** f() |
Linksverschiebungszuweisung | x <<= f() |
x = x << f() |
Rechtsverschiebungszuweisung | x >>= f() |
x = x >> f() |
Unsigned-Rechtsverschiebungszuweisung | x >>>= f() |
x = x >>> f() |
Bitweises UND-Zuweisung | x &= f() |
x = x & f() |
Bitweises XOR-Zuweisung | x ^= f() |
x = x ^ f() |
Bitweises ODER-Zuweisung | x |= f() |
x = x | f() |
Logisches UND-Zuweisung | x &&= f() |
x && (x = f()) |
Logisches ODER-Zuweisung | x ||= f() |
x || (x = f()) |
Nullish Coalescing-Zuweisung | 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 machen. Zum Beispiel:
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, führen Zuweisungen an Eigenschaften dieses Ausdrucks keine Zuordnungen durch:
const val = 0;
val.x = 3;
console.log(val.x); // Prints undefined.
console.log(val); // Prints 0.
Im strikten Modus wirft der obige Code einen Fehler, da man keine Eigenschaften zu primitiven Datenwerten zuweisen kann.
Es ist ein Fehler, Werte an nicht modifizierbare Eigenschaften oder an Eigenschaften eines Ausdrucks ohne Eigenschaften (null
oder undefined
) zuzuweisen.
Dekonstruktion
Für komplexere Zuweisungen ist der Destrukturierungszuweisung Syntax ein JavaScript-Ausdruck, der es ermöglicht, Daten aus Arrays oder Objekten mit einer Syntax zu extrahieren, die der Konstruktion von Array- und Objekt-Literalen entspricht.
Ohne Destrukturierung benötigt 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 separate Variablen mit einer einzigen 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().
Allerdings, wie bei anderen Ausdrücken, werten Zuweisungsausdrücke wie x = f()
in einen Ergebniswert aus. Obwohl dieser Ergebniswert normalerweise nicht verwendet wird, kann er dann von einem anderen Ausdruck verwendet werden.
Das Verketten 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. Nichtsdestotrotz kann das Verketten und Verschachteln von Zuweisungen manchmal vorkommen, sodass es wichtig ist, verstehen zu können, wie sie funktionieren.
Durch das Verketten oder Verschachteln eines Zuweisungsausdrucks kann das Ergebnis selbst einer anderen Variablen zugewiesen werden. Es kann protokolliert werden, es kann in ein Array-Literal oder einen 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 Spalte "Bedeutung" der obigen Tabelle. Das bedeutet, dass x = f()
in das Ergebnis von f()
auswertet, x += f()
in die resultierende Summe von x + f()
, x **= f()
in die resultierende Potenz von x ** f()
, und so weiter.
Im Fall von logischen Zuweisungen wie x &&= f()
, x ||= f()
, und x ??= f()
ist der Rückgabewert der des logischen Vorgangs ohne die Zuweisung, also x && f()
, x || f()
, und x ?? f()
, jeweils.
Wenn diese Ausdrücke ohne Klammern oder andere Gruppierungsoperatoren wie Array-Literale verkettet werden, werden die Zuweisungsausdrücke von rechts nach links gruppiert (sie sind rechtsassoziativ), aber sie werden von links nach rechts ausgewertet.
Beachten Sie, dass für alle Zuweisungsoperatoren außer =
selbst, die resultierenden Werte immer auf den Werten der Operanden vor der Operation basieren.
Zum Beispiel, vorausgesetzt, dass die folgenden 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 Sie diese drei Beispiele:
y = x = f();
y = [f(), x = g()];
x[f()] = g();
Bewertung Beispiel 1
y = x = f()
entspricht y = (x = f())
, weil der Zuweisungsoperator =
rechtsassoziativ ist. Es wird jedoch von links nach rechts ausgewertet:
- Der Zuweisungsausdruck
y = x = f()
beginnt mit der Auswertung.- Das
y
auf der linken Seite dieser Zuweisung wird zu einer Referenz auf die Variable mit dem Nameny
ausgewertet. - Der Zuweisungsausdruck
x = f()
beginnt mit der Auswertung.- Das
x
auf der linken Seite dieser Zuweisung wird zu einer Referenz auf die Variable mit dem Namenx
ausgewertet. - Der Funktionsaufruf
f()
druckt "F!" in die Konsole aus und wertet dann zu der Zahl2
aus. - Dieses
2
-Ergebnis vonf()
wirdx
zugewiesen.
- Das
- Der Zuweisungsausdruck
x = f()
hat die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vonx
, der2
ist. - Dieses
2
-Ergebnis wird wiederumy
zugewiesen.
- Das
- Der Zuweisungsausdruck
y = x = f()
hat die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vony
– der2
ist.x
undy
werden auf2
gesetzt, und die Konsole hat "F!" gedruckt.
Bewertung Beispiel 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 wird zu einer Referenz auf die Variable mit dem Nameny
ausgewertet. - Das innere Array-Literal
[ f(), x = g() ]
beginnt mit der Auswertung.- Der Funktionsaufruf
f()
druckt "F!" in die Konsole aus und wertet dann zu der Zahl2
aus. - Der Zuweisungsausdruck
x = g()
beginnt mit der Auswertung.- Das
x
auf der linken Seite dieser Zuweisung wird zu einer Referenz auf die Variable mit dem Namenx
ausgewertet. - Der Funktionsaufruf
g()
druckt "G!" in die Konsole aus und wertet dann zu der Zahl3
aus. - Dieses
3
-Ergebnis vong()
wirdx
zugewiesen.
- Das
- Der Zuweisungsausdruck
x = g()
hat die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vonx
, der3
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 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 die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vony
– das2, 3]
.x
ist jetzt3
, undy
ist jetzt[ 2, 3 ]
, und die Konsole hat "F!" und dann "G!" gedruckt.
Bewertung Beispiel 3
x[f()] = g()
wird ebenfalls von links nach rechts ausgewertet. (Dieses Beispiel nimmt an, dass x
bereits einem Objekt zugewiesen wurde. Für weitere Informationen über Objekte lesen Sie Arbeiten mit Objekten.)
- Der Zuweisungsausdruck
x[f()] = g()
beginnt mit der Auswertung.- Der Eigenschaftszugriff
x[f()]
auf der linken Seite dieser Zuweisung beginnt mit der Auswertung.- Das
x
in diesem Eigenschaftszugriff wird zu einer Referenz auf die Variable mit dem Namenx
ausgewertet. - Der Funktionsaufruf
f()
druckt "F!" in die Konsole aus und wertet dann zu der Zahl2
aus.
- Das
- Der Eigenschaftszugriff
x[f()]
auf dieser Zuweisung hat die Auswertung abgeschlossen; sein Ergebnis ist eine variable Eigenschaftsreferenz:x[2]
. - Der Funktionsaufruf
g()
druckt "G!" in die Konsole aus und wertet dann zu der Zahl3
aus. - Dieses
3
wird jetztx[2]
zugewiesen. (Dieser Schritt wird nur erfolgreich sein, wennx
einem Objekt zugeordnet wurde.)
- Der Eigenschaftszugriff
- Der Zuweisungsausdruck
x[f()] = g()
hat die Auswertung abgeschlossen; sein Ergebnis ist der neue Wert vonx[2]
– das3
.x[2]
ist jetzt3
, und die Konsole hat "F!" und dann "G!" gedruckt.
Vermeiden von Zuweisungsketten
Das Verketten von Zuweisungen oder das Verschachteln von Zuweisungen in anderen Ausdrücken kann zu überraschendem Verhalten führen. Aus diesem Grund wird verkettete Zuweisung in derselben Anweisung als schlechter Stil angesehen.
Insbesondere funktioniert es oft nicht, eine Vari
ablenkette in einer const
, let
oder var
Anweisung zu platzieren. Nur die äußerste/linkeste Variable wird deklariert; andere Variablen innerhalb der Zuweisungskette werden von der const
/let
/var
Anweisung nicht deklariert.
Zum Beispiel:
const z = y = x = f();
Diese Anweisung scheint die Variablen x
, y
und z
zu deklarieren.
Jedoch wird tatsächlich nur die Variable z
deklariert.
y
und x
sind entweder ungültige Referenzen auf nicht existierende Variablen (im strikten Modus) oder, schlimmer noch, würden globale Variablen für x
und y
im nachlässigen Modus implizit 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, Zeichenketten-, logische oder Objekt Werte sein.
Zeichenketten werden basierend auf der standardmäßigen lexikographischen Sortierung 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 geeigneten Typ für den Vergleich zu konvertieren.
Dieses Verhalten führt in der Regel dazu, dass die Operanden numerisch verglichen werden.
Die einzigen Ausnahmen von der Typkonvertierung bei Vergleichen betreffen die ===
und !==
Operatoren, die strikte Gleichheits- und 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 wahr zurückgeben |
---|---|---|
Gleich (== )
|
Gibt true zurück, wenn die Operanden gleich sind. |
3 == var1
3 == '3'
|
Ungleich (!= )
|
Gibt true zurück, wenn die Operanden ungleich sind. |
var1 != 4
|
Strikt gleich (=== )
|
Gibt true zurück, wenn die Operanden gleich und vom gleichen Typ sind. Siehe auch Object.is und
Gleichheit in JS.
|
3 === var1 |
Strikt ungleich (!== )
|
Gibt true zurück, wenn die Operanden vom gleichen Typ, aber nicht gleich sind, oder von verschiedenen Typen 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 Pfeilfunktionen.
Arithmetische Operatoren
Ein arithmetischer Operator nimmt numerische Werte (entweder Literale oder Variablen) als seine Operanden und gibt einen einzelnen numerischen Wert zurück.
Die Standard-Arithmetikoperatoren 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 Division durch Null Infinity
ergibt). Zum Beispiel:
1 / 2; // 0.5
1 / 2 === 1.0 / 2.0; // this is true
Zusätzlich zu den Standard-Arithmetikoperationen (+
, -
, *
, /
) bietet JavaScript die in der folgenden Tabelle aufgeführten arithmetischen Operatoren:
Operator | Beschreibung | Beispiel |
---|---|---|
Rest (% )
|
Binärer Operator. Gibt den ganzzahligen Rest der Division der beiden Operanden zurück. | 12 % 5 gibt 2 zurück. |
Inkrement (++ )
|
Unärer Operator. Addiert eins zu seinem Operanden. Wenn als Präfix-Operator
(++x ) verwendet, gibt den Wert seines Operanden nach dem Hinzufügen von eins
zurück; wenn als Postfix-Operator (x++ ) verwendet, gibt 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 für den Inkrement-Operator. |
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, wenn er es nicht schon ist. |
|
Exponentiationsoperator (** )
|
Berechnet die Grundzahl zur Exponenten -Potenz,
das ist, Grundzahl^Exponenten
|
2 ** 3 gibt 8 zurück.10 ** -1
gibt 0.1 zurück.
|
Bitweise Operatoren
Ein bitweiser Operator behandelt seine Operanden als ein Set von 32 Bit (Nullen und Einsen), anstatt als Dezimal-, Hexadezimal- oder Oktalzahlen. Zum Beispiel hat die Dezimalzahl neun eine binäre Darstellung von 1001. Bitweise Operatoren führen ihre Operationen auf solchen binären Darstellungen durch, geben jedoch standardmäßige JavaScript-numerische Werte zurück.
Die folgende Tabelle fasst die bitweisen Operatoren von JavaScript zusammen.
Operator | Nutzung | 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 NOT | ~ a |
Invertiert die Bits seines Operanden. |
Linksverschiebung | a << b |
Verschiebt a in binärer Darstellung b Bits nach links, wobei Nullen von rechts hereingeschoben werden. |
Vorzeichenbehaftete Rechtsverschiebung | a >> b |
Verschiebt a in binärer Darstellung b Bits nach rechts, wobei verschobene Bits verworfen werden. |
Vorzeichenlose Rechtsverschiebung | a >>> b |
Verschiebt a in binärer Darstellung b Bits nach rechts, wobei verschobene Bits verworfen werden und Nullen von links hereingeschoben werden. |
Bitweise logische Operatoren
Konzeptionell arbeiten die bitweisen logischen Operatoren wie folgt:
-
Die Operanden werden in 32-Bit-Ganzzahlen konvertiert und durch eine Reihe von Bits (Nullen und Einsen) ausgedrückt. Zahlen mit mehr als 32 Bits werden ihre bedeutendsten 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äre Darstellung von neun 1001 und die binäre Darstellung von fünfzehn 1111. Wenn die bitweisen Operatoren auf diese Werte angewendet werden, sind die Ergebnisse wie folgt:
Ausdruck | Ergebnis | Binäre Beschreibung |
---|---|---|
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 NOT-Operator invertiert werden und dass Werte mit dem bedeutendsten (linken) Bit, das auf 1 gesetzt ist, negative Zahlen (Zweierkomplement-Darstellung) darstellen. ~x
wertet zu demselben Wert aus, wie -x - 1
auswertet.
Bitweise Verschiebeoperatoren
Die bitweisen Verschiebeoperatoren nehmen zwei Operanden: der erste ist eine zu verschiebende Menge, 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 32-Bit-Ganzzahlen und geben ein Ergebnis vom Typ Number
oder BigInt
zurück: Insbesondere, wenn der Typ
des linken Operanden BigInt
ist, geben sie einen BigInt
zurück;
anderenfalls geben sie einen Number
zurück.
Die Verschiebeoperatoren sind in der folgenden Tabelle aufgeführt.
Operator | Beschreibung | Beispiel |
---|---|---|
Linksverschiebung ( << )
|
Dieser Operator verschiebt den ersten Operanden um die angegebene Anzahl von Bits nach links. Überschüssige Bits, die nach links verschoben werden, werden verworfen. Null-Bits werden von rechts eingeschoben. |
9<<2 ergibt 36, da 1001 verschoben um 2 Bits nach links 100100 wird, was 36 ist.
|
Vorzeichenbehaftete Rechtsverschiebung (>> )
|
Dieser Operator verschiebt den ersten Operanden um die angegebene Anzahl von Bits nach rechts. Überschüssige Bits, die nach rechts verschoben werden, werden verworfen. Kopien des linken Bits werden von links hereingeschoben. |
9>>2 ergibt 2, da 1001 verschoben um 2 Bits nach rechts 10 wird, was 2 ist. Ebenfalls, -9>>2 ergibt -3, da das Vorzeichen erhalten bleibt.
|
Vorzeichenlose Rechtsverschiebung (>>> )
|
Dieser Operator verschiebt den ersten Operanden um die angegebene Anzahl von Bits nach rechts. Überschüssige Bits, die nach rechts verschoben werden, werden verworfen. Null-Bits werden von links hereingeschoben. |
19>>>2 ergibt 4, da 10011 verschoben um 2 Bits nach rechts 100 wird, was 4 ist. Für nicht-negative Zahlen erzeugen vorzeichenlose und vorzeichenbehaftete 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.
Allerdings geben die &&
, ||
und ??
Operatoren tatsächlich den Wert eines der angegebenen Operanden zurück, sodass, wenn diese Operatoren mit nicht-booleschen Werten verwendet werden, sie einen nicht-booleschen Wert zurückgeben können. Als solche werden sie angemessener als "Wertauswahl-Operatoren" bezeichnet.
Die logischen Operatoren sind in der folgenden Tabelle beschrieben.
Operator | Nutzung | Beschreibung |
---|---|---|
Logisches UND (&& )
|
expr1 && expr2 |
Gibt expr1 zurück, wenn es in false umgewandelt werden kann;
ansonsten gibt es expr2 zurück. Wenn es mit booleschen Werten verwendet wird, gibt && true zurück, wenn beide Operanden wahr sind; andernfalls gibt false zurück.
|
Logisches ODER (|| )
|
expr1 || expr2 |
Gibt expr1 zurück, wenn es in true umgewandelt werden kann;
andernfalls gibt es expr2 zurück. Wenn es mit booleschen Werten verwendet wird, gibt || true zurück, wenn einer der Operanden wahr ist; wenn beide falsch sind, gibt false zurück.
|
Nullish Coalescing-Operator (?? )
|
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 einziger Operand in true umgewandelt werden kann; andernfalls, liefert true .
|
Beispiele für Ausdrücke, die in false
umgewandelt werden können, sind solche, die zu null
, 0
, 0n
, NaN
, der leeren Zeichenkette (""
) 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 ??
(Nullish Coalescing) 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. entweder null
oder undefined
. ??
ist eine bessere Alternative zu ||
, um Standardwerte für Werte festzulegen, die null
oder undefined
sein könnten, insbesondere wenn Werte wie ''
oder 0
gültige Werte sind und der Standard nicht gelten 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
Da logische Ausdrücke von links nach rechts ausgewertet werden, werden sie nach möglichen "Kurzschluss"-Bedingungen mittels der folgenden Regeln getestet:
falsch && irgendetwas
ist ein Kurzschluss, der zum falschen Wert auswertet.wahr || irgendetwas
ist ein Kurzschluss, der zum wahren Wert auswertet.nicht Nullish ?? irgendetwas
ist ein Kurzschluss, der zum nicht-nullish Wert auswertet.
Die Regeln der Logik garantieren, dass diese Bewertungen immer korrekt sind. Beachten Sie, dass der irgendetwas Teil der obigen Ausdrücke nicht ausgewertet wird, sodass alle Nebeneffekte dieses nicht in Kraft treten.
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 die Unsigned-Rechtsverschiebung (>>>
), die für BigInt-Werte nicht definiert ist. Dies liegt daran, dass ein BigInt keine feste Breite hat und daher technisch gesehen kein "höchstes Bit" hat.
const d = 8n >>> 2n; // TypeError: BigInts have no unsigned right shift, use >> instead
BigInts und Zahlen sind nicht wechselseitig austauschbar – man kann sie nicht in Berechnungen mischen.
const a = 1n + 2; // TypeError: Cannot mix BigInt and other types
Dies liegt daran, dass BigInt weder ein Obermenge noch eine Untermenge von Zahlen ist. BigInts haben eine höhere Präzision als Zahlen bei der Darstellung von großen Ganzzahlen, können jedoch keine Dezimalzahlen darstellen, sodass eine implizite Konvertierung auf beiden Seiten möglicherweise Präzision verliert. Verwenden Sie eine explizite Konvertierung, um anzugeben, ob Sie die Operation als Zahlenoperation oder als BigInt-Operation durchführen möchten.
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-Werte angewendet werden können, fügt der Verkettungsoperator (+) zwei String-Werte zusammen und gibt einen weiteren String zurück, der die Vereinigung der beiden Operand-Strings ist.
Zum Beispiel,
console.log("my " + "string"); // console logs the string "my string".
Der Kurzschreib-Zuweisungsoperator +=
kann ebenfalls verwendet werden, um Strings zu verketten.
Zum Beispiel,
let myString = "alpha";
myString += "bet"; // evaluates to "alphabet" and assigns this value to myString.
Bedingungsoperator (ternär)
Der Bedingungsoperator ist der einzige JavaScript-Operator, der drei Operanden annimmt. Der Operator kann einen von zwei Werten basierend auf einer Bedingung haben. Die Syntax lautet:
condition ? val1 : val2
Wenn Bedingung
wahr ist, hat der Operator den Wert von val1
. Andernfalls hat er den Wert von val2
. Sie können den Bedingungsoperator überall dort verwenden, wo Sie einen Standardoperator verwenden würden.
Zum Beispiel,
const status = age >= 18 ? "adult" : "minor";
Diese Anweisung weist der Variable status
den Wert "Erwachsener" zu, wenn Alter
achtzehn oder mehr ist. Andernfalls weist sie status
den Wert "Minderjähriger" zu.
Komma-Operator
Der Komma-Operator (,
) wertet beide Operanden aus und gibt den Wert des letzten Operanden zurück. Dieser Operator wird hauptsächlich in einer for
-Schleife verwendet, um mehrere Variablen bei jedem Durchlauf der Schleife zu aktualisieren. Es wird als schlechter Stil angesehen, ihn anderswo zu verwenden, wenn es nicht notwendig ist. Oft können und sollten stattdessen zwei separate Anweisungen verwendet werden.
Zum Beispiel, wenn a
ein zweidimensionales 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 Diagonalelemente 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 loeschen
Operator löscht eine Eigenschaft eines Objekts. Die Syntax lautet:
delete object.property;
delete object[propertyKey];
delete objectName[index];
wobei objekt
der Name eines Objekts ist, eigenschaft
eine vorhandene Eigenschaft ist, und eigenschaftSchlüssel
eine Zeichenkette oder ein Symbol ist, die auf eine bestehende Eigenschaft verweist.
Wenn der loeschen
-Operator erfolgreich ist, entfernt er die Eigenschaft vom Objekt. Der Versuch, darauf zuzugreifen, ergibt anschließend undefined
. Der loeschen
-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 loeschen
. Dies wird jedoch als schlechte Praxis angesehen – versuchen Sie, es zu vermeiden. Wenn Sie eine Array-Eigenschaft löschen, wird die Länge des Arrays nicht beeinflusst und andere Elemente werden nicht neu indexiert. 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, nutzen Sie die verschiedenen Array-Methoden wie splice
.
typeof
Der typeof
-Operator gibt einen String zurück, der den Typ des nicht ausgewerteten Operanden angibt. Operand
ist der String, die Variable, das Schlüsselwort oder das Objekt, für das der Typ zurückgegeben werden soll. Die Klammern sind optional.
Angenommen, Sie definieren die folgenden Variablen:
const myFun = new Function("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 folgende Ergebnisse zurück:
typeof true; // returns "boolean"
typeof null; // returns "object"
Für eine Zahl oder einen String gibt der typeof
-Operator folgende Ergebnisse zurück:
typeof 62; // returns "number"
typeof "Hello world"; // returns "string"
Für Eigenschaftswerte gibt der typeof
-Operator den Typ des Wertes zurück, den die Eigenschaft enthält:
typeof document.lastModified; // returns "string"
typeof window.length; // returns "number"
typeof Math.LN2; // returns "number"
Für Methoden und Funktionen gibt der typeof
-Operator folgende Ergebnisse zurück:
typeof blur; // returns "function"
typeof eval; // returns "function"
typeof parseInt; // returns "function"
typeof shape.split; // returns "function"
Für vordefinierte Objekte gibt der typeof
-Operator folgende Ergebnisse 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 gibt an, dass ein Ausdruck ausgewertet werden soll, ohne einen Wert zurückzugeben. Ausdruck
ist ein JavaScript-Ausdruck, der ausgewertet werden soll. Die den Ausdruck umgebenden Klammern sind optional, sind jedoch aus stilistischen Gründen sinnvoll, um Vorrangprobleme zu vermeiden.
Relationsoperatoren
Ein Relationsoperator vergleicht seine Operanden und gibt einen booleschen Wert zurück, basierend darauf, ob der Vergleich wahr ist.
in
Der in
-Operator gibt true
zurück, wenn die angegebene Eigenschaft in dem angegebenen Objekt existiert. Die Syntax lautet:
propNameOrNumber in objectName
wobei propNameOrNumber
ein Ausdruck ist, der einen Eigenschaftsnamen oder einen 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 vom angegebenen Objekttyp ist. Die Syntax lautet:
object instanceof objectType
wobei object
das Objekt ist, das gegen objectType
getestet werden soll, und objectType
ein Konstruktor ist, der einen Typ darstellt, wie z. B. Map
oder Array
.
Verwenden Sie instanceof
, wenn Sie zur Laufzeit den Typ eines Objekts bestätigen müssen. Zum Beispiel können Sie beim Abfangen von Ausnahmen zu unterschiedlichen Ausnahmebehandlungscodezuschnitten entsprechend dem Typ der geworfenen Ausnahme verzweigen.
Zum Beispiel bestimmt der folgende Code mit instanceof
, ob obj
ein Map
-Objekt ist. Da obj
ein Map
-Objekt ist, werden die Anweisungen innerhalb des if
-Blocks ausgeführt.
const obj = new Map();
if (obj instanceof Map) {
// statements to execute
}
Grundlegende Ausdrücke
Alle Operatoren arbeiten letztlich mit einem oder mehreren grundlegenden Ausdrücken. Diese grundlegenden Ausdrücke umfassen Bezeichner und Literale, aber es gibt noch einige andere Arten. Sie werden kurz vorgestellt, und ihre Semantik wird in ihren jeweiligen Referenzabschnitten im Detail beschrieben.
this
Verwenden Sie das this
-Schlüsselwort, um auf das aktuelle Objekt zu verweisen. Im Allgemeinen bezieht sich this
in einer Methode auf das aufrufende Objekt. Verwenden Sie this
entweder mit der Punkt- oder der Klammer-Notation:
this["propertyName"];
this.propertyName;
Angenommen, eine Funktion namens validate
validiert eine value
-Eigenschaft eines Objekts, gegeben das Objekt und die hohen und niedrigen Werte:
function validate(obj, lowVal, highVal) {
if (obj.value < lowVal || obj.value > highVal) {
console.log("Invalid Value!");
}
}
Sie könnten validate
in jedem Formelement onChange
-Ereignishandler aufrufen und this
verwenden, um es an das Formelement zu übergeben, wie im folgenden Beispiel:
<p>Enter a number between 18 and 99:</p>
<input type="text" name="age" size="3" onChange="validate(this, 18, 99);" />
Gruppierungsoperator
Der Gruppierungsoperator ( )
steuert die Vorrangordnung der Auswertung in
Ausdrücken. Zum Beispiel können Sie die Multiplikation und Division vor der Addition und Subtraktion außer Kraft setzen, um die Addition zuerst auszuwerten.
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
Eigenschaftszugriff
Der Eigenschaftszugriff Syntax holt Eigenschaftswerte auf Objekten, indem entweder Punkt-Notation oder Klammer-Notation verwendet wird.
object.property;
object["property"];
Der Leitfaden zu Arbeiten mit Objekten geht näher auf Objekteigenschaften ein.
Optional Chaining
Die Optional Chaining Syntax (?.
) führt die verkettete Operation auf einem Objekt aus, wenn es definiert und nicht-null
ist, und beendet andernfalls die Operation und gibt undefined
zurück. Dies ermöglicht es Ihnen, mit einem Wert zu operieren, der möglicherweise null
oder undefined
ist, ohne dass ein TypeError
verursacht 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 Elternobjekt eines Objekts aufzurufen. Es ist nützlich bei Klassen, um den Elternkonstruktor aufzurufen, zum Beispiel.
super(args); // calls the parent constructor.
super.functionOnParent(args);