Erklärung des Betreibers

Operator

Klassische echte Fragen

  • Unter welchen Umständen wird im folgenden Code die Ausgabeanweisung ausgeführt und 1 ausgegeben ?
var a = ?;
if(a == 1 && a == 2 && a == 3){
    
    
 	console.log(1);
}

1. Arithmetische Operatoren

JavaScript bietet insgesamt 10 arithmetische Operatoren zur Vervollständigung grundlegender arithmetischer Operationen.

  • Additionsoperator :x + y
  • Subtraktionsoperator :x - y
  • Multiplikationsoperator :x * y
  • Divisionsbetreiber :x / y
  • Exponentialoperator :x ** y
  • Restbetreiber :x % y
  • Inkrementoperator : ++xoderx++
  • Dekrementoperator : --xoderx--
  • Numerische Operatoren :+x
  • Negative numerische Operatoren :-x

Subtraktions-, Multiplikations- und Divisionsoperationen sind relativ einfach, dh die Durchführung entsprechender mathematischer Operationen.

Im Folgenden werden mehrere andere arithmetische Operatoren beschrieben, wobei der Schwerpunkt auf dem Additionsoperator liegt.

Additionsoperator

(1) Grundregeln

Der Additionsoperator ( +) ist der am häufigsten verwendete Operator, um die Summe zweier Zahlen zu ermitteln.

1 + 1 // 2

JavaScript ermöglicht nicht-numerische Additionen.

true + true // 2
1 + true // 2

Im obigen Code ist die erste Zeile die Addition zweier boolescher Werte und die zweite Zeile die Addition des Werts und des booleschen Werts. In beiden Fällen werden die booleschen Werte automatisch in numerische Werte umgewandelt und anschließend addiert.

Das Besondere daran ist, dass beim Hinzufügen von zwei Zeichenfolgen der Additionsoperator zu einem Verkettungsoperator wird, der eine neue Zeichenfolge zurückgibt und die beiden ursprünglichen Zeichenfolgen verkettet.

'a' + 'bc' // "abc"

Wenn ein Operator ein String und der andere ein Nicht-String ist, wird der Nicht-String in einen String konvertiert und verkettet.

1 + 'a' // "1a"
false + 'a' // "falsea"

Der Additionsoperator entscheidet zur Laufzeit, ob eine Addition oder eine Verbindung durchgeführt wird. Mit anderen Worten: Unterschiedliche Operatoren führen zu unterschiedlichem grammatikalischem Verhalten. Dieses Phänomen wird als „Überladung“ bezeichnet. Da der Additionsoperator überladen ist, führt er möglicherweise zwei Operationen aus. Sie müssen daher bei der Verwendung vorsichtig sein.

'3' + 4 + 5 // "345"
3 + 4 + '5' // "75"

Im obigen Code führen unterschiedliche Positionen der Zeichenfolge aufgrund der Reihenfolge der Operationen von links nach rechts zu unterschiedlichen Ergebnissen.

Mit Ausnahme des Additionsoperators werden andere arithmetische Operatoren (z. B. Subtraktion, Division und Multiplikation) nicht überladen. Ihre Regeln lauten: Alle Operatoren werden in numerische Werte umgewandelt und dann werden die entsprechenden mathematischen Operationen ausgeführt.

1 - '2' // -1
1 * '2' // 2
1 / '2' // 0.5

Im obigen Code konvertieren die Subtraktions-, Divisions- und Multiplikationsoperatoren Zeichenfolgen automatisch in numerische Werte und führen dann Operationen aus.

(2) Hinzufügen von Objekten

Wenn der Operator ein Objekt ist, muss er vor dem Hinzufügen in einen primitiven Typwert konvertiert werden.

var obj = {
    
     p: 1 };
obj + 2 // "[object Object]2"

Im obigen Code objlautet der Wert des in den ursprünglichen Typ konvertierten Objekts [object Object], und wenn es hinzugefügt wird, 2wird das obige Ergebnis erhalten.

Das Objekt wird gemäß den folgenden Regeln in einen primitiven Typwert umgewandelt.

Zunächst werden die Methoden des Objekts valueOfautomatisch aufgerufen.

var obj = {
    
     p: 1 };
obj.valueOf() // { p: 1 }

Im Allgemeinen gibt die valueOfMethode des Objekts immer das Objekt selbst zurück. Zu diesem Zeitpunkt wird die Methode des Objekts automatisch aufgerufen toStringund in eine Zeichenfolge konvertiert.

var obj = {
    
     p: 1 };
obj.valueOf().toString() // "[object Object]"

Die Methoden des Objekts toStringgeben standardmäßig zurück [object Object], sodass das Ergebnis des vorherigen Beispiels erhalten wird.

Nachdem Sie diese Regel kennen, können Sie Ihre eigenen valueOfMethoden oder toStringMethoden definieren, um die gewünschten Ergebnisse zu erzielen.

var obj = {
    
    
  valueOf: function () {
    
    
    return 1;
  }
};

obj + 2 // 3

Im obigen Code haben wir die Methode objdes zurückzugebenden Objekts definiert , also haben wir es bekommen . Da die Methode in diesem Beispiel direkt einen primitiven Typwert zurückgibt, wird die Methode nicht mehr aufgerufen.valueOf1obj + 23valueOftoString

Unten finden Sie ein Beispiel für eine benutzerdefinierte toStringMethode.

var obj = {
    
    
  toString: function () {
    
    
    return 'hello';
  }
};

obj + 2 // "hello2"

Im obigen Code gibt die Objektmethode objeinen toStringString zurück hello. Wie bereits erwähnt, wird der Additionsoperator zum Verbindungsoperator und gibt die verbundene Zeichenfolge zurück, solange ein Operator eine Zeichenfolge ist.

Hier gibt es einen Sonderfall: Wenn der Operator eine DateInstanz eines Objekts ist, toStringwird zuerst die Methode ausgeführt.

var obj = new Date();
obj.valueOf = function () {
    
     return 1 };
obj.toString = function () {
    
     return 'hello' };

obj + 2 // "hello2"

Im obigen Code objist das Objekt eine Instanz eines Objekts, und die Methoden und Methoden Datewerden angepasst und die Ergebnismethode wird zuerst ausgeführt.valueOftoStringtoString

Restoperator

Der Restoperator ( %) gibt den Rest zurück, der sich aus der Division des vorherigen Operators durch den nächsten Operator ergibt.

12 % 5 // 2

Es ist zu beachten, dass das Vorzeichen des Operationsergebnisses durch das Vorzeichen des ersten Operators bestimmt wird.

-1 % 2 // -1
1 % -2 // 1

Um also den korrekten Restwert für eine negative Zahl zu erhalten, können Sie zunächst die Absolutwertfunktion verwenden.

// 错误的写法
function isOdd(n) {
    
    
  return n % 2 === 1;
}
isOdd(-5) // false
isOdd(-4) // false

// 正确的写法
function isOdd(n) {
    
    
  return Math.abs(n % 2) === 1;
}
isOdd(-5) // true
isOdd(-4) // false

Der Restoperator kann auch für Gleitkommaarithmetik verwendet werden. Da Gleitkommazahlen jedoch keine exakten Werte sind, können keine völlig genauen Ergebnisse erzielt werden.

6.5 % 2.1
// 0.19999999999999973

Inkrement- und Dekrementoperatoren

Die Inkrementierungs- und Dekrementierungsoperatoren sind unäre Operatoren und erfordern nur einen Operator. Ihre Funktion besteht darin, den Operator zunächst in einen numerischen Wert umzuwandeln und dann 1 zu addieren oder 1 zu subtrahieren. Sie ändern die ursprüngliche Variable.

var x = 1;
++x // 2
x // 2

--x // 1
x // 1

Nachdem die Variable im obigen Code xinkrementiert wurde, gibt sie zurück 2, dekrementiert sich dann selbst und gibt zurück 1. In beiden Fällen xändert sich der Wert der ursprünglichen Variablen.

Nach einer Operation ändert sich der Wert der Variablen. Dieser Effekt wird als Nebeneffekt der Operation bezeichnet. Die Inkrementierungs- und Dekrementierungsoperatoren sind die einzigen beiden Operatoren, die Nebenwirkungen haben, und keiner der anderen Operatoren ändert den Wert der Variablen.

Bei den Selbstinkrementierungs- und Selbstdekrementierungsoperatoren ist eines zu beachten: Nachdem die Variable platziert wurde, wird zuerst der Wert vor der Variablenoperation zurückgegeben und dann die Selbstinkrementierungs-/Selbstdekrementierungsoperation Vor der Variablen wird zuerst die Selbstinkrementierung/Selbstdekrementierung durchgeführt. Subtraktionsoperation, und dann wird der Wert nach der Variablenoperation zurückgegeben.

var x = 1;
var y = 1;

x++ // 1
++y // 2

Im obigen Code xwird zuerst der aktuelle Wert zurückgegeben und dann erhöht, sodass wir erhalten 1. yZuerst wird er erhöht, und dann wird der neue Wert zurückgegeben, sodass wir erhalten 2.

numerischer Operator, negativer numerischer Operator

Der numerische Operator ( +) verwendet ebenfalls das Pluszeichen, ist jedoch ein unärer Operator (der nur einen Operanden erfordert), während der Additionsoperator ein binärer Operator ist (der zwei Operanden erfordert).

Numerische Operatoren werden verwendet, um einen beliebigen Wert in einen numerischen Wert umzuwandeln ( Numberwie Funktionen).

+true // 1
+[] // 0
+{
    
    } // NaN

Der obige Code zeigt an, dass nicht numerische Werte nach Durchlaufen numerischer Operatoren zu numerischen Werten werden (die letzte Zeile NaNist ebenfalls ein numerischer Wert). Spezifische Typkonvertierungsregeln finden Sie im Kapitel „Datentypkonvertierung“.

Der negative numerische Operator ( -) hat ebenfalls die Funktion, einen Wert in einen numerischen Wert umzuwandeln, der erhaltene Wert ist jedoch positiv und negativ. Die gemeinsame Verwendung zweier negativer numerischer Operatoren entspricht numerischen Operatoren.

var x = 1;
-x // -1
-(-x) // 1

Die Klammern in der letzten Zeile des obigen Codes sind wichtig, sonst wird es zu einem Dekrementoperator.

Sowohl der numerische Operator als auch der negative numerische Operator geben einen neuen Wert zurück, ohne den Wert der ursprünglichen Variablen zu ändern.

Exponentialoperator

Der Exponentenoperator ( **) schließt die Exponentialoperation ab. Der erstere Operator ist die Basis und der letztere Operator ist der Exponent.

2 ** 4 // 16

Beachten Sie, dass der Exponentenoperator rechtsassoziativ und nicht linksassoziativ ist. Das heißt, wenn mehrere Exponentenoperatoren zusammen verwendet werden, wird die Berechnung ganz rechts zuerst durchgeführt.

// 相当于 2 ** (3 ** 2)
2 ** 3 ** 2
// 512

Da im obigen Code der Exponentialoperator rechtsassoziativ ist, wird der zweite Exponentialoperator zuerst berechnet, nicht der erste.

Aufgabenverwalter

Zuweisungsoperatoren werden verwendet, um Variablen Werte zuzuweisen.

Der gebräuchlichste Zuweisungsoperator ist natürlich das Gleichheitszeichen ( =).

// 将 1 赋值给变量 x
var x = 1;

// 将变量 y 的值赋值给变量 x
var x = y;

Der Zuweisungsoperator kann auch mit anderen Operatoren zu Variationen kombiniert werden. Unten ist die Kombination mit arithmetischen Operatoren.

// 等同于 x = x + y
x += y

// 等同于 x = x - y
x -= y

// 等同于 x = x * y
x *= y

// 等同于 x = x / y
x /= y

// 等同于 x = x % y
x %= y

// 等同于 x = x ** y
x **= y

Das Folgende ist eine Kombination mit bitweisen Operatoren (für bitweise Operatoren siehe die Einleitung später).

// 等同于 x = x >> y
x >>= y

// 等同于 x = x << y
x <<= y

// 等同于 x = x >>> y
x >>>= y

// 等同于 x = x & y
x &= y

// 等同于 x = x | y
x |= y

// 等同于 x = x ^ y
x ^= y

Diese zusammengesetzten Zuweisungsoperatoren führen zunächst die angegebene Operation aus und geben dann den erhaltenen Wert an die Variable auf der linken Seite zurück.

2. Vergleichsoperatoren

Vergleichsoperatoren werden verwendet, um die Größe zweier Werte zu vergleichen und dann einen booleschen Wert zurückzugeben, der angibt, ob die angegebene Bedingung erfüllt ist.

2 > 1 // true

Der obige Code vergleicht 2, ob er größer als ist oder nicht, 1und gibt zurück true.

Beachten Sie, dass Vergleichsoperatoren Werte aller Art vergleichen können, nicht nur numerische Werte.

JavaScript bietet insgesamt 8 Vergleichsoperatoren.

  • >größer als Operator
  • <weniger als Betreiber
  • <=kleiner oder gleich dem Operator
  • >=Größer oder gleich dem Operator
  • ==Gleichheitsoperator
  • ===strikter Gleichheitsoperator
  • !=Ungleichheitsoperator
  • !==strikter Ungleichheitsoperator

Diese acht Vergleichsoperatoren sind in zwei Kategorien unterteilt: Gleichheitsvergleich und Nichtgleichheitsvergleich. Die Regeln der beiden sind unterschiedlich. Bei ungleichen Vergleichen prüft der Algorithmus zunächst, ob die beiden Operatoren beide Zeichenfolgen sind. Wenn ja, vergleichen Sie sie in Wörterbuchreihenfolge (wobei tatsächlich Unicode-Codepunkte verglichen werden); andernfalls wandeln Sie beide Operatoren in numerische Werte um , und vergleichen Sie dann die numerischen Werte.

Ungleichheitsoperator: Vergleich von Zeichenfolgen

Zeichenfolgen werden in lexikografischer Reihenfolge verglichen.

'cat' > 'dog' // false
'cat' > 'catalog' // false

Die JavaScript-Engine vergleicht intern zunächst den Unicode-Codepunkt des ersten Zeichens. Wenn sie gleich sind, vergleichen Sie den Unicode-Codepunkt des zweiten Zeichens usw.

'cat' > 'Cat' // true'

Im obigen Code ist der cUnicode-Codepunkt ( 99) in Kleinbuchstaben größer als der CUnicode-Codepunkt ( 67) in Großbuchstaben und wird daher zurückgegeben true.

Da alle Zeichen über Unicode-Codepunkte verfügen, können auch chinesische Zeichen verglichen werden.

'大' > '小' // false

Im obigen Code ist der „große“ Unicode-Codepunkt 22823 und der „kleine“ 23567, daher wird er zurückgegeben false.

Ungleichheitsoperator: Vergleich von Nicht-Strings

Wenn mindestens einer der beiden Operatoren keine Zeichenfolge ist, muss er in die folgenden zwei Situationen unterteilt werden.

(1) Wert des primitiven Typs

Wenn es sich bei beiden Operatoren um Werte vom primitiven Typ handelt, werden sie zunächst in numerische Werte umgewandelt und dann verglichen.

5 > '4' // true
// 等同于 5 > Number('4')
// 即 5 > 4

true > false // true
// 等同于 Number(true) > Number(false)
// 即 1 > 0

2 > true // true
// 等同于 2 > Number(true)
// 即 2 > 1

Im obigen Code werden Zeichenfolgen und boolesche Werte zunächst in numerische Werte umgewandelt und dann verglichen.

NaNHier müssen Sie auf den Vergleich mit achten . Jeder Wert (einschließlich NaNsich selbst), der NaNmit dem Ungleichheitsoperator verglichen wird, wird zurückgegeben false.

1 > NaN // false
1 <= NaN // false
'1' > NaN // false
'1' <= NaN // false
NaN > NaN // false
NaN <= NaN // false

(2) Objekt

Wenn der Operator ein Objekt ist, wird er in einen primitiven Typwert konvertiert und dann verglichen.

Um ein Objekt in einen Wert eines primitiven Typs umzuwandeln, muss der Algorithmus zunächst valueOfdie Methode aufrufen. Wenn das zurückgegebene Objekt noch ein Objekt ist, rufen Sie die toStringMethode auf. Eine ausführliche Erklärung finden Sie im Kapitel „Datentypkonvertierung“.

var x = [2];
x > '11' // true
// 等同于 [2].valueOf().toString() > '11'
// 即 '2' > '11'

x.valueOf = function () {
    
     return '1' };
x > '11' // false
// 等同于 [2].valueOf() > '11'
// 即 '1' > '11'

Das Gleiche gilt für Vergleiche zwischen zwei Objekten.

[2] > [1] // true
// 等同于 [2].valueOf().toString() > [1].valueOf().toString()
// 即 '2' > '1'

[2] > [11] // true
// 等同于 [2].valueOf().toString() > [11].valueOf().toString()
// 即 '2' > '11'

{
    
     x: 2 } >= {
    
     x: 1 } // true
// 等同于 { x: 2 }.valueOf().toString() >= { x: 1 }.valueOf().toString()
// 即 '[object Object]' >= '[object Object]'

strikter Gleichheitsoperator

JavaScript bietet zwei Gleichheitsoperatoren: ==und ===.

Einfach ausgedrückt besteht der Unterschied zwischen ihnen darin, dass der Gleichheitsoperator ( ==) vergleicht, ob zwei Werte gleich sind, und der strikte Gleichheitsoperator ( ===) vergleicht, ob sie „den gleichen Wert“ haben. Wenn die beiden Werte nicht vom gleichen Typ sind, gibt der strikte Gleichheitsoperator ( ===) sie direkt zurück false, während der Gleichheitsoperator ( ==) sie in denselben Typ konvertiert und dann den strikten Gleichheitsoperator zum Vergleich verwendet.

(1) Verschiedene Arten von Werten

Wenn die beiden Werte unterschiedlichen Typs sind, geben Sie sie direkt zurück false.

1 === "1" // false
true === "true" // false

Der obige Code vergleicht den numerischen Wert 1mit der Zeichenfolge „1“ und den booleschen Wert truemit der Zeichenfolge "true". Da die Typen unterschiedlich sind, sind die Ergebnisse beide false.

(2) Primitive Typwerte derselben Klasse

Beim Vergleich primitiver Typwerte (numerische Werte, Zeichenfolgen, boolesche Werte) desselben Typs werden die Werte zurückgegeben, wenn sie gleich sind. trueWenn die Werte unterschiedlich sind, werden sie zurückgegeben false.

1 === 0x1 // true

Der obige Code vergleicht Dezimal- 1und Hexadezimalzahlen 1und gibt sie zurück, da Typ und Wert gleich sind true.

Es ist zu beachten, dass es NaNkeinem Wert entspricht (einschließlich sich selbst). Außerdem ist positiv 0gleich negativ 0.

NaN === NaN  // false
+0 === -0 // true

(3) Zusammengesetzter Typwert

Beim Vergleich von Daten zweier zusammengesetzter Typen (Objekte, Arrays, Funktionen) geht es nicht darum, zu vergleichen, ob ihre Werte gleich sind, sondern darum, ob sie auf dieselbe Adresse verweisen.

{
    
    } === {
    
    } // false
[] === [] // false
(function () {
    
    } === function () {
    
    }) // false

Der obige Code vergleicht jeweils zwei leere Objekte, zwei leere Arrays und zwei leere Funktionen, und die Ergebnisse sind nicht gleich. Der Grund dafür ist, dass bei zusammengesetzten Typwerten die strikte Gleichheitsoperation vergleicht, ob sie sich auf dieselbe Speicheradresse beziehen, während die Werte leerer Objekte, leerer Arrays und leerer Funktionen auf beiden Seiten des Operators alle in unterschiedlichen Speichern gespeichert werden Adressen. Das Ergebnis ist natürlich false.

Zwei Variablen sind gleich, wenn sie sich auf dasselbe Objekt beziehen.

var v1 = {
    
    };
var v2 = v1;
v1 === v2 // true

Beachten Sie, dass bei Vergleichen zwischen zwei Objekten der strikte Gleichheitsoperator Adressen vergleicht, während der Größer-als- oder Kleiner-als-Operator Werte vergleicht.

var obj1 = {
    
    };
var obj2 = {
    
    };

obj1 > obj2 // false
obj1 < obj2 // false
obj1 === obj2 // false

Von den drei oben genannten Vergleichen vergleichen die ersten beiden Werte und der letzte Adressen, sodass sie alle zurückgegeben werden false.

(4) undefiniert und null

undefinedund sind nullsich selbst strikt gleich.

undefined === undefined // true
null === null // true

Da der Standardwert nach der Deklaration einer Variablen lautet undefined, sind zwei Variablen, die nur deklariert, aber keinem Wert zugewiesen werden, gleich.

var v1;
var v2;
v1 === v2 // true

strikter Ungleichheitsoperator

Der strikte Gleichheitsoperator verfügt über einen entsprechenden „strengen Ungleichheitsoperator“ ( !==), dessen Algorithmus darin besteht, zuerst das Ergebnis des strikten Gleichheitsoperators zu finden und dann den entgegengesetzten Wert zurückzugeben.

1 !== '1' // true
// 等同于
!(1 === '1')

Im obigen Code wird das Ausrufezeichen !verwendet, um den entgegengesetzten Wert des folgenden Ausdrucks zu finden.

Gleichheitsoperator

Der Gleichheitsoperator funktioniert genau wie der strikte Gleichheitsoperator, wenn er zum Vergleichen von Daten desselben Typs verwendet wird.

1 == 1.0
// 等同于
1 === 1.0

Beim Vergleich von Daten unterschiedlichen Typs konvertiert der Gleichheitsoperator zunächst den Datentyp und vergleicht ihn dann mit dem strikten Gleichheitsoperator. Das Folgende ist in mehrere Situationen unterteilt, um die Regeln für den Vergleich verschiedener Wertetypen miteinander zu erörtern.

(1) Wert des primitiven Typs

Primitive Typwerte werden in numerische Werte umgewandelt und verglichen.

1 == true // true
// 等同于 1 === Number(true)

0 == false // true
// 等同于 0 === Number(false)

2 == true // false
// 等同于 2 === Number(true)

2 == false // false
// 等同于 2 === Number(false)

'true' == true // false
// 等同于 Number('true') === Number(true)
// 等同于 NaN === 1

'' == 0 // true
// 等同于 Number('') === 0
// 等同于 0 === 0

'' == false  // true
// 等同于 Number('') === Number(false)
// 等同于 0 === 0

'1' == true  // true
// 等同于 Number('1') === Number(true)
// 等同于 1 === 1

'\n  123  \t' == 123 // true
// 因为字符串转为数字时,省略前置和后置的空格

Der obige Code wandelt sowohl Zeichenfolgen als auch boolesche Werte in numerische Werte um und vergleicht sie anschließend.

(2) Vergleich von Objekten und primitiven Typwerten

Wenn ein Objekt (hier bezieht sich auf ein verallgemeinertes Objekt, einschließlich Arrays und Funktionen) mit einem Wert des Originaltyps verglichen wird, wird das Objekt in einen Wert des Originaltyps konvertiert und dann verglichen.

Rufen Sie insbesondere valueOf()zuerst die Methode des Objekts auf. Wenn Sie den Wert des ursprünglichen Typs erhalten, vergleichen Sie ihn gemäß den Regeln im vorherigen Abschnitt miteinander. Wenn Sie das Objekt erhalten, rufen Sie die Methode erneut auf, um die Zeichenfolgenform zu toString()erhalten , und dann vergleichen.

Unten finden Sie ein Beispiel für den Vergleich eines Arrays mit einem Wert eines primitiven Typs.

// 数组与数值的比较
[1] == 1 // true

// 数组与字符串的比较
[1] == '1' // true
[1, 2] == '1,2' // true

// 对象与布尔值的比较
[1] == true // true
[2] == true // false

Im obigen Beispiel ruft die JavaScript-Engine zuerst die Methode [1]des Arrays für das Array auf valueOf(). Da die Rückgabe immer noch ein Array ist, ruft sie dann toString()die Methode des Arrays auf, um die Zeichenfolgenform abzurufen, und vergleicht sie dann entsprechend Regeln im vorherigen Abschnitt.

Hier ist ein direkteres Beispiel.

const obj = {
    
    
  valueOf: function () {
    
    
    console.log('执行 valueOf()');
    return obj;
  },
  toString: function () {
    
    
    console.log('执行 toString()');
    return 'foo';
  }
};

obj == 'foo'
// 执行 valueOf()
// 执行 toString()
// true

Im obigen Beispiel objhandelt es sich um ein Objekt mit einem Benutzerdefiniert valueOf()und toString()einer Methode. Wenn dieses Objekt 'foo'mit einer Zeichenfolge verglichen wird, werden die Methoden valueOf()und toString()nacheinander aufgerufen und schließlich zurückgegeben 'foo', sodass das Vergleichsergebnis lautet true.

(3) undefiniert und null

undefinedund nullwerden nur zurückgegeben, wenn sie mit sich selbst oder untereinander verglichen werden true; beim Vergleich mit Werten anderer Typen ist das Ergebnis false.

undefined == undefined // true
null == null // true
undefined == null // true

false == null // false
false == undefined // false

0 == null // false
0 == undefined // false

(4) Nachteile des Gleichheitsoperators

Die vom Gleichheitsoperator verborgene Typkonvertierung kann zu kontraintuitiven Ergebnissen führen.

0 == ''             // true
0 == '0'            // true

2 == true           // false
2 == false          // false

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

Die oben genannten Ausdrücke unterscheiden sich von der Intuition und es kann leicht zu Fehlern kommen. Daher wird empfohlen, den Gleichheitsoperator ( ==) nicht zu verwenden und am besten nur den strikten Gleichheitsoperator ( ===) zu verwenden.

Ungleichheitsoperator

Der Gleichheitsoperator verfügt über einen entsprechenden „Ungleichheitsoperator“ ( !=). Sein Algorithmus besteht darin, zuerst das Ergebnis des Gleichheitsoperators zu finden und dann den entgegengesetzten Wert zurückzugeben.

1 != '1' // false

// 等同于
!(1 == '1')

3. Boolesche Operatoren (logische Operatoren)

Boolesche Operatoren werden zum Konvertieren von Ausdrücken in boolesche Werte verwendet. Insgesamt gibt es vier Operatoren.

  • Negationsoperator:!
  • Und (Gewerkschafts-)Operator:&&
  • Oder Betreiber:||
  • Ternärer Operator:?:

Negationsoperator (!)

Der Negationsoperator ist ein Ausrufezeichen, das verwendet wird, um einen booleschen Wert in sein Gegenteil umzuwandeln, z. B. truewird zu false, falsewird true.

!true // false
!false // true

Nicht-boolesche Werte werden vom Negationsoperator in boolesche Werte umgewandelt. Es kann auf diese Weise gespeichert werden: Die folgenden sechs Werte sind invertiert true, und alle anderen Werte sind false.

  • undefined
  • null
  • false
  • 0
  • NaN
  • leere Zeichenfolge ( '')
!undefined // true
!null // true
!0 // true
!NaN // true
!"" // true

!54 // false
!'hello' // false
![] // false
!{
    
    } // false

Im obigen Code wird der Wert unabhängig von der Art nach der Invertierungsoperation zu einem booleschen Wert.

Wenn Sie zwei aufeinanderfolgende Invertierungsoperationen für einen Wert ausführen, entspricht dies der Konvertierung in den entsprechenden booleschen Wert, der den Booleangleichen Effekt wie eine Funktion hat. Dies ist eine häufig verwendete Methode zur Typkonvertierung.

!!x
// 等同于
Boolean(x)

Unabhängig von der xArt des Werts im obigen Code wird er nach zwei Negationsoperationen zum Booleangleichen booleschen Wert wie das Funktionsergebnis. Zweimaliges Negieren ist also nur eine Abkürzung für die Umwandlung eines Werts in einen booleschen Wert.

Und Operator (&&)

Und der Operator ( &&) wird oft verwendet, um mehrere Ausdrücke auszuwerten.

Seine Operationsregeln lauten: Wenn der boolesche Wert des ersten Operators ist true, wird der Wert des zweiten Operators zurückgegeben (beachten Sie, dass es sich um einen Wert und nicht um einen booleschen Wert handelt); wenn der boolesche Wert des ersten Operators ist, falsedann wird direkt zurückgegeben Der Wert des ersten Operators, und der zweite Operator wird nicht mehr ausgewertet.

't' && '' // ""
't' && 'f' // "f"
't' && (1 + 2) // 3
'' && 'f' // ""
'' && '' // ""

var x = 1;
(1 - 1) && ( x += 1) // 0
x // 1

Da im letzten Beispiel des obigen Codes der boolesche Wert des ersten Operators des UND-Operators lautet false, wird sein Wert direkt zurückgegeben, 0ohne den zweiten Operator auszuwerten, sodass xsich der Wert der Variablen nicht ändert.

Dieser Mechanismus des Überspringens des zweiten Operators wird als „Kurzschluss“ bezeichnet. Einige Programmierer verwenden es gerne, um ifdie Struktur zu ersetzen. Das Folgende ist beispielsweise ein Teil ifdes Strukturcodes, der mit dem Operator und umgeschrieben werden kann.

if (i) {
    
    
  doSomething();
}

// 等价于

i && doSomething();

Die beiden Arten, den obigen Code zu schreiben, sind gleichwertig, aber der Zweck der letzteren ist nicht leicht zu erkennen und das Debuggen ist nicht einfach. Es wird empfohlen, sie mit Vorsicht zu verwenden.

falseUnd Operatoren können in Verbindung mit mehreren Operatoren verwendet werden. In diesem Fall wird der Wert des Ausdrucks zurückgegeben, dessen erster boolescher Wert zurückgegeben wird . Wenn alle Ausdrücke einen booleschen Wert haben true, wird der Wert des letzten Ausdrucks zurückgegeben.

true && 'foo' && '' && 4 && 'foo' && true
// ''

1 && 2 && 3
// 3

Im obigen Code in Beispiel 1 falseist der erste Ausdruck mit einem booleschen Wert der dritte Ausdruck, sodass eine leere Zeichenfolge erhalten wird. Im zweiten Beispiel haben alle Ausdrücke boolesche Werte true, sodass der Wert des letzten Ausdrucks zurückgegeben wird 3.

ODER-Operator (||)

Der OR-Operator ( ||) wird auch bei der Auswertung mehrerer Ausdrücke verwendet. Seine Betriebsregeln lauten: Wenn der erste Operator einen booleschen Wert hat true, wird der Wert des ersten Operators zurückgegeben und der zweite Operator nicht ausgewertet; wenn der erste Operator einen booleschen Wert hat false, wird der Wert des zweiten Operators zurückgegeben.

't' || '' // "t"
't' || 'f' // "t"
'' || 'f' // "f"
'' || '' // ""

Auch für diesen Betreiber gelten die Kurzschlussregeln.

var x = 1;
true || (x = 2) // true
x // 1

Im obigen Code ist der erste Operator des or-Operators true, also kehren Sie direkt zurück true, ohne den zweiten Operator auszuführen. Daher xhat sich der Wert von nicht geändert. Dieser Mechanismus zur Steuerung, ob der zweite Ausdruck nur über den Wert des ersten Ausdrucks ausgeführt werden soll, wird als „Abkürzung“ bezeichnet.

trueDer OR-Operator kann mehrfach verwendet werden und gibt den Wert des Ausdrucks zurück, dessen erster boolescher Wert ist . Wenn alle Ausdrücke wahr sind false, wird der Wert des letzten Ausdrucks zurückgegeben.

false || 0 || '' || 4 || 'foo' || true
// 4

false || 0 || ''
// ''

Im obigen Code in Beispiel 1 ist der erste trueAusdruck mit einem booleschen Wert der vierte Ausdruck, sodass der Wert 4 erhalten wird. In Beispiel 2 lauten die booleschen Werte aller Ausdrücke false, sodass der Wert des letzten Ausdrucks zurückgegeben wird.

Der OR-Operator wird häufig verwendet, um einen Standardwert für eine Variable festzulegen.

function saveText(text) {
    
    
  text = text || '';
  // ...
}

// 或者写成
saveText(this.text || '')

Der obige Code gibt an, dass der Parameter standardmäßig auf eine leere Zeichenfolge gesetzt ist, wenn beim Aufruf der Funktion kein Parameter angegeben wird.

Ternärer bedingter Operator (?:)

Der ternäre Bedingungsoperator besteht aus einem Fragezeichen (?) und einem Doppelpunkt (:), um drei Ausdrücke zu trennen. Es ist der einzige Operator in der JavaScript-Sprache, der drei Operatoren erfordert. trueGibt den Wert des zweiten Ausdrucks zurück, wenn der erste Ausdruck ein boolescher Wert ist , andernfalls wird der Wert des dritten Ausdrucks zurückgegeben.

't' ? 'hello' : 'world' // "hello"
0 ? 'hello' : 'world' // "world"

tDie booleschen Werte der Summen im obigen Code 0lauten jeweils truesum false, sodass die Werte des zweiten und dritten Ausdrucks jeweils zurückgegeben werden.

Im Allgemeinen if...elsehaben ternäre bedingte Ausdrücke die gleiche Ausdruckswirkung wie Sätze, und was der erstere ausdrücken kann, kann der letztere auch ausdrücken. Es gibt jedoch einen großen Unterschied zwischen den beiden: if...elseEs handelt sich um eine Anweisung ohne Rückgabewert; der ternäre bedingte Ausdruck ist ein Ausdruck und hat einen Rückgabewert. Wenn daher ein Rückgabewert erforderlich ist, können nur ternäre bedingte Ausdrücke verwendet werden, nicht jedoch if..else.

console.log(true ? 'T' : 'F');

Im obigen Code console.logmuss der Parameter der Methode ein Ausdruck sein. In diesem Fall können nur ternäre bedingte Ausdrücke verwendet werden. Wenn Sie eine Anweisung verwenden möchten if...else, müssen Sie den gesamten Codewortlaut ändern.

4. Bitoperatoren

Bitweise Operatoren konvertieren Operanden in binäre 32 -Bit-Ganzzahlen und führen dann Operationen für jedes Bit aus. Zum Beispiel:

Die 32 Bits von 5 sind:

00000000000000000000000000000101

Die 32 Bits von 100 sind:

00000000000000000000000001100100

Die 32 Bits von 15 sind:

00000000000000000000000000001111

Bitweise NICHT

Der bitweise NOT-Operator ~wandelt die Zahl in eine binäre 32-Bit-Ganzzahl um und invertiert dann jedes Bit. Alle Einsen werden zu Nullen, alle Nullen werden zu Einsen

Zum Beispiel:

Die 32 Bits von 5 sind:

00000000000000000000000000000101

32 Bits von ~5 sind:

11111111111111111111111111111010  

Der konvertierte Wert ist -6

Bitweises NICHT negiert im Wesentlichen die Operanden und subtrahiert 1.

bitweises UND

Der bitweise ODER-Operator &wandelt zwei Zahlen in eine binäre 32-Bit-Ganzzahl um und führt eine bitweise UND-Operation für jedes Bit der beiden Zahlen durch. Die Regeln für bitweises UND lauten wie folgt:

erste Nummer zweite Nummer Ergebnis
1 1 1
1 0 0
0 1 0
0 0 0

Konkrete Beispiele:

console.log(12 & 10); // 8

Die 32-Bit-Binärdarstellung von 12 lautet: 1100.
Die 32-Bit-Binärdarstellung von 10 lautet: 1010

Das Ergebnis der bitweisen UND-Verknüpfung ist: 1000

bitweise oder

Der bitweise ODER-Operator |wandelt zwei Zahlen in eine binäre 32-Bit-Ganzzahl um und führt eine bitweise ODER-Operation für jedes Bit der beiden Zahlen durch. Die Regeln für bitweises ODER lauten wie folgt:

erste Nummer zweite Nummer Ergebnis
1 1 1
1 0 1
0 1 1
0 0 0

Konkrete Beispiele:

console.log(12 | 10); // 14

Die 32-Bit-Binärdarstellung von 12 lautet: 1100.
Die 32-Bit-Binärdarstellung von 10 lautet: 1010

Das Ergebnis der bitweisen ODER-Verknüpfung ist: 1110

bitweises XOR

Der bitweise ODER-Operator ^wandelt zwei Zahlen in binäre 32-Bit-Ganzzahlen um und führt für jedes Bit der beiden Zahlen eine bitweise XOR-Operation durch. Die Betriebsregel lautet: Wenn die beiden Bits unterschiedlich sind, wird 1 zurückgegeben, und wenn die beiden Bits gleich sind, wird 0 zurückgegeben, wie in der folgenden Tabelle gezeigt:

erste Nummer zweite Nummer Ergebnis
1 1 0
1 0 1
0 1 1
0 0 0

Konkrete Beispiele:

console.log(12 ^ 10); // 6

Die 32-Bit-Binärdarstellung von 12 lautet: 1100.
Die 32-Bit-Binärdarstellung von 10 lautet: 1010

Das Ergebnis der bitweisen XOR-Verknüpfung ist: 0110

Wenn bitweises XOR ein nicht ganzzahliger Wert ist und nur einer der beiden Operanden wahr ist, wird 1 zurückgegeben. Wenn beide Operanden wahr oder beide falsch sind, wird 0 zurückgegeben. Das Beispiel sieht wie folgt aus:

console.log(true ^ "Hello"); // 1
console.log(false ^ "Hello"); // 0
console.log(true ^ true); // 0
console.log("Hello" ^ "Hello"); // 0
console.log(false ^ false); // 0
console.log(true ^ false); // 1

Beachten Sie, dass „Hallo hier“ in NaN konvertiert wird

bitweise Verschiebung

Die bitweisen Verschiebungsoperatoren <<und >>verschieben alle Bits um einen angegebenen Betrag nach links oder rechts, wodurch eine Zahl effektiv mit einer angegebenen Potenz von 2 multipliziert oder dividiert wird.

<<: Mit 2 mit der angegebenen Potenz multiplizieren

console.log(2<<2); // 8

2 mal 2 hoch 2 erhöht

00000010 umgewandelt in 00001000

>>: Durch 2 mit der angegebenen Potenz dividieren

console.log(16>>1); // 8

16 dividiert durch 2 hoch 1

00010000 wird in 00001000 umgewandelt

5. Andere Betreiber

Void- Operator

Die Funktion des void- Operators besteht darin, einen Ausdruck auszuführen und dann keinen Wert oder undefiniert zurückzugeben .

void 0 // undefined
void(0) // undefined

Die oben genannten zwei Möglichkeiten, den Void- Operator zu schreiben, sind beide korrekt. Es empfiehlt sich die letztgenannte Form, also immer Klammern zu verwenden.

Da der Void- Operator eine hohe Priorität hat, kann es leicht zu falschen Ergebnissen kommen, wenn keine Klammern verwendet werden.

Beispielsweise entspricht „void 4 + 7“ tatsächlich „(void 4) + 7“ .

Unten finden Sie ein Beispiel für einen Void- Operator.

var x = 3;
void (x = 5) //undefined
x // 5

Der Hauptzweck dieses Operators ist das Lesezeichen-Tool des Browsers ( Bookmarklet ) und das Einfügen von Codes in Hyperlinks, um Webseitensprünge zu verhindern.

Bitte schauen Sie sich den Code unten an.

<script>
function f() {
    
    
  console.log('Hello World');
}
</script>
<a href="http://example.com" onclick="f(); return false;">点击</a>

Im obigen Code wird nach dem Klicken auf den Link zuerst der Code von onclick ausgeführt . Da onclick false zurückgibt , springt der Browser nicht zu example.com .

Der Void- Operator kann die obige Schreibmethode ersetzen.

<a href="javascript: void(f())">文字</a>

Hier ist ein realistischeres Beispiel, bei dem der Benutzer auf den Link klickt, um das Formular abzuschicken, aber keine Seitenumleitung erfolgt.

<a href="javascript: void(document.form.submit())">
  提交
</a>

Komma-Operator

Der Kommaoperator wird verwendet, um zwei Ausdrücke auszuwerten und den Wert des letzteren Ausdrucks zurückzugeben.

'a', 'b' // "b"

var x = 0;
var y = (x++, 10);
x // 1
y // 10

Im obigen Code gibt der Kommaoperator den Wert des letztgenannten Ausdrucks zurück.

Eine Verwendung des Kommaoperators besteht darin, Hilfsoperationen auszuführen, bevor ein Wert zurückgegeben wird.

var value = (console.log('Hi!'), true);
// Hi!

value // true

Im obigen Code wird zuerst die Operation vor dem Komma ausgeführt und dann der Wert nach dem Komma zurückgegeben.

6. Reihenfolge der Operationen

Priorität

Die Priorität ( Operator Precedence ) verschiedener Operatoren in JavaScript ist unterschiedlich. Operatoren mit höherer Priorität werden zuerst ausgeführt, Operatoren mit niedrigerer Priorität werden später ausgeführt.

4 + 5 * 6 // 34

Im obigen Code hat der Multiplikationsoperator ( * ) eine höhere Priorität als der Additionsoperator ( + ), daher wird zuerst die Multiplikation und dann die Addition durchgeführt, was dem Folgenden entspricht.

4 + (5 * 6) // 34

Wenn mehrere Operatoren miteinander vermischt werden, führt dies oft zu verwirrendem Code.

var x = 1;
var arr = [];

var y = arr.length <= 0 || arr[0] === undefined ? x : arr[0];

Im obigen Code ist der Wert der Variablen y schwer zu erkennen, da dieser Ausdruck fünf Operatoren umfasst. Es ist nicht leicht, sich zu merken, welcher die höchste Priorität hat.

Gemäß der Sprachspezifikation ist die Rangfolge dieser fünf Operatoren von hoch nach niedrig: kleiner oder gleich ( <= ), strikte Gleichheit ( === ) oder ( || ), ternär ( ?: ), Gleichheitszeichen ( = ). Daher ist die tatsächliche Reihenfolge der Operationen für den obigen Ausdruck wie folgt.

var y = ((arr.length <= 0) || (arr[0] === undefined)) ? x : arr[0];

Es ist schwierig und unnötig, sich die Priorität aller Operatoren zu merken.

Die Funktion von Klammern

Klammern können verwendet werden, um die Priorität einer Operation zu erhöhen, da ihre Priorität die höchste ist, d. h. der Ausdruck in Klammern wird zuerst ausgewertet.

(4 + 5) * 6 // 54

Im obigen Code wird aufgrund der Verwendung von Klammern die Addition vor der Multiplikation durchgeführt.

Die Prioritätsstufen der Operatoren sind sehr kompliziert und unterliegen strengen Regeln. Daher wird empfohlen, immer Klammern zu verwenden, um sicherzustellen, dass die Reihenfolge der Operationen klar und lesbar ist, was für die Codepflege und das Debuggen von entscheidender Bedeutung ist.

Klammern sind übrigens keine Operatoren, sondern ein Syntaxkonstrukt. Es hat zwei Verwendungszwecke: Zum einen wird der Ausdruck in Klammern gesetzt, um die Priorität der Operation zu erhöhen, und zum anderen wird der Funktion gefolgt, um die Funktion aufzurufen.

Beachten Sie, dass Klammern, da sie keine Operatoren sind, keine Auswirkung auf die Auswertung haben und nur die Priorität der Operation ändern.

var x = 1;
(x) = 2;

Wenn in der zweiten Zeile des obigen Codes die Klammern einen Bewertungseffekt haben, wird daraus 1 = 2 , was zu einem Fehler führt. Allerdings funktioniert der obige Code, der überprüft, ob die Klammern nur die Priorität und nicht die Auswertung ändern.

Dies bedeutet auch, dass der gesamte Ausdruck keine Wirkung hat, wenn er in Klammern eingeschlossen ist.

(expression)
// 等同于
expression

Wenn Sie eine Funktion in Klammern setzen, wird die Funktion selbst zurückgegeben. Wenn die Klammern unmittelbar auf die Funktion folgen, bedeutet dies, dass die Funktion aufgerufen wird.

function f() {
    
    
  return 1;
}

(f) // function f(){return 1;}
f() // 1

Im obigen Code gibt die in Klammern gesetzte Funktion die Funktion selbst zurück, und die auf die Funktion folgenden Klammern rufen die Funktion auf.

Es können nur Ausdrücke in Klammern gesetzt werden. Wenn eine Anweisung in Klammern steht, wird ein Fehler gemeldet.

(var a = 1)
// SyntaxError: Unexpected token var

Linksverknüpfung und Rechtsverknüpfung

Bei Operatoren mit derselben Prioritätsebene tritt bei gleichzeitigem Auftreten ein Problem mit der Berechnungsreihenfolge auf.

a OP b OP c

Im obigen Code steht OP für den Operator. Es kann auf zwei Arten interpretiert werden.

// 方式一
(a OP b) OP c

// 方式二
a OP (b OP c)

Die mit den beiden oben genannten Methoden erzielten Berechnungsergebnisse sind häufig unterschiedlich.

Die erste Möglichkeit besteht darin, die beiden Operanden auf der linken Seite miteinander zu kombinieren. Der Operator, der diese Interpretationsmethode verwendet, wird als „Links-nach- rechts-Assoziativitätsoperator “ bezeichnet .

Die zweite Möglichkeit besteht darin, die beiden Operanden auf der rechten Seite zu kombinieren. Ein solcher Operator wird als „Rechts-nach-Links-Assoziativität“-Operator ( Rechts-nach-Links-Assoziativität ) bezeichnet.

Die meisten Operatoren in der JavaScript- Sprache sind „linksassoziativ“, siehe das Beispiel des Additionsoperators unten.

x + y + z

// 引擎解释如下
(x + y) + z

Im obigen Code werden x und y kombiniert und ihre Budgetergebnisse werden dann mit z berechnet .

Eine Handvoll Operatoren sind „rechtsassoziativ“, darunter vor allem der Zuweisungsoperator ( = ) und der ternäre Bedingungsoperator ( ?: ).

w = x = y = z;
q = a ? b : c ? d : e ? f : g;

Der obige Code wird wie folgt erklärt.

w = (x = (y = z));
q = a ? b : (c ? d : (e ? f : g));

In den beiden obigen Codezeilen werden die Operanden auf der rechten Seite kombiniert.

Auch der Exponentenoperator (**) ist rechtsassoziativ.

2 ** 3 ** 2
// 相当于 2 ** (3 ** 2)
// 512

Antworten auf echte Fragen

  • Unter welchen Umständen wird im folgenden Code die Ausgabeanweisung ausgeführt und 1 ausgegeben ?
var a = ?;
if(a == 1 && a == 2 && a == 3){
    
    
 	console.log(1);
}

Referenzantwort:

Methode 1: Verwenden Sie die Methode toString()

var a = {
     
     
    i: 1,
    toString() {
     
     
        return a.i++;
    }
}
if (a == 1 && a == 2 && a == 3) {
     
     
    console.log('1');
}

Methode 2: Verwenden Sie die Methode valueOf()

var a = {
     
     
    i: 1,
    valueOf() {
     
     
        return a.i++
    }
}
if (a == 1 && a == 2 && a == 3) {
     
     
    console.log('1');
}

- EOF -

Ich denke du magst

Origin blog.csdn.net/qq_53461589/article/details/132739427
Empfohlen
Rangfolge