JavaScript -Entwickler Douglas Crockford bezeichnete einmal die Operatoren von JavaScript ==
und !=
als "böse Zwillinge", die vermieden werden sollten. Sobald Sie sie jedoch verstanden haben, sind diese Betreiber nicht so schlimm und können tatsächlich nützlich sein. In diesem Artikel werden ==
und !=
erklärt, wie sie funktionieren, und Ihnen helfen, sie besser zu verstehen.
Schlüsselpunkte
==
Operatoren in JavaScript sind nicht von Natur aus böse; !=
===
für direkte Typ- und Wertvergleiche ohne Gießen, was klarer ist und normalerweise empfohlen wird, unerwartete Ergebnisse zu vermeiden. Verwenden Sie !==
und ==
, wenn Sie Werte gießen oder vergleichen müssen, deren Typen sich dynamisch ändern können. !=
==
Vergleiche ausgeht, um die Ergebnisse genauer vorherzusagen und gemeinsame Fallstricke zu vermeiden. !=
==
in verschiedenen Szenarien ausgeführt werden, z. B. den Vergleich von Zeichenfolgen oder Objekten mit Originalwerten, um das Verständnis zu konsolidieren. !=
==
nicht beängstigend sind, erfordern sie ein gutes Verständnis für die Regeln von JavaScript -Typen, um effektiv und sicher in Code zu verwenden. lokal. !=
problematisch und ==
Operatoren !=
und ===
und !==
und ==
. Verstehen, warum es zwei Sätze von Gleichstellungsoperatoren gibt und in denen Situationen für viele Menschen die Verwirrungsquelle für viele Menschen waren. Die Operatoren !=
und ===
sind nicht schwer zu verstehen. Wenn die beiden Operandentypen gleich sind und die Werte gleich sind, gibt !==
===
und true
!==
zurück. Wenn der Wert oder der Typ jedoch unterschiedlich ist, gibt false
===
false
!==
zurück. Die Operatoren true
und ==
verhalten sich genauso, wenn die beiden Operanden Typen gleich sind. Wenn die Typen jedoch unterschiedlich sind, übergibt JavaScript einen Operand !=
an einen anderen Typ, um den Operanden vor dem Vergleich kompatibel zu machen. Die Ergebnisse sind oft verwirrend, wie folgt:
"this_is_true" == false // false "this_is_true" == true // false
berechnet. Zusätzliche Verwirrung tritt auf, wenn Sie annehmen, dass die Passbeziehung (wenn a gleich B und B gleich c) gelten sollte: true
"this_is_true" == false // false "this_is_true" == true // false
Dieses Beispiel zeigt, dass ==
keine Transitivität hat. Wenn die leere Zeichenfolge gleich der Zahl 0 entspricht und die Zahl 0 gleich der Zeichenfolge ist, die aus Zeichen 0 besteht, sollte die leere Zeichenfolge gleich der aus 0 bestehenden Zeichenfolge sein. Aber das ist nicht der Fall. Wenn beim Vergleich von Operanden durch ==
oder !=
ein inkompatibler Typ auftritt, schenkt JavaScript einen Typ an einen anderen, um ihn vergleichbar zu machen. Umgekehrt führt bei der Verwendung von ===
und !==
niemals Typ -Gips (was zu einer leichten Leistungsverbesserung führt). Aufgrund verschiedener Typen gibt ===
im zweiten Beispiel immer false
==
zurück. Verständnis von Regeln, die steuern, wie JavaScript Operanden an verschiedene Typen ausgeht, sodass die beiden Operandentypen kompatibel sind, bevor Sie !=
und ==
anwenden, können Sie feststellen, wann es besser ist, !=
und ==
zu verwenden, und Vertrauen in das Vertrauen zu haben Verwenden dieser Operatoren. Im nächsten Abschnitt werden wir die mit den Operatoren !=
und
Wie funktioniert ==
!=
und ?
Der beste Weg, um zu lernen, wie ==
und !=
Arbeiten die Spezifikationen der ECMascript -Sprachspezifikationen untersuchen. Dieser Abschnitt konzentriert sich auf ECMascript 262. In Abschnitt 11.9 der Spezifikation wird der Gleichstellungsoperator eingeführt. Die Operatoren ==
und !=
werden in der Syntaxproduktion EqualityExpression
und EqualityExpressionNoIn
angezeigt. (Im Gegensatz zur ersten Generation vermeidet die zweite Generation den in
-Operator.) Überprüfen Sie die unten gezeigte EqualityExpression
-Gerstellung.
'' == 0 // true 0 == '0' // true '' == '0' // false
nach dieser Generation ist der gleiche Ausdruck entweder ein relationaler Ausdruck oder ein gleicher Ausdruck, der gleich einem relationalen Ausdruck ist, oder ein gleicher Ausdruck, der nicht gleich einem relationalen Ausdruck usw. ist. (Ich habe ==
und !=
übersehen, die sich nicht mit diesem Artikel beziehen.) Abschnitt 11.9.1 enthält die folgenden Informationen darüber, wie ===
funktioniert: !==
==
wird wie folgt berechnet:funktioniert:Sei
EqualityExpression : EqualityExpression == RelationalExpression
das Ergebnis der Berechnung
Abschnitt 11.9.2 enthält ähnliche Informationen darüber, wie- .
seinlref
EqualityExpression
Sei- .
das Ergebnis der Berechnunglval
GetValue(lref)
Sei- .
seinrref
RelationalExpression
Sei- .
zurück. (Siehe 11.9.3.)rval
GetValue(rref)
Gibt das Ergebnis der Durchführung eines abstrakten Gleichstellungsvergleichsrval == lval
!=
wird wie folgt berechnet:
- Sei
lref
das Ergebnis der BerechnungEqualityExpression
.- Sei
lval
seinGetValue(lref)
.- Sei
rref
das Ergebnis der BerechnungRelationalExpression
.- Sei
rval
seinGetValue(rref)
.- Sei
r
das Ergebnis einer abstrakten Gleichstellungsvergleichrval != lval
. (Siehe 11.9.3.)- Wenn
r
true
ist, returnfalse
. Ansonsten returntrue
.
lref
und rref
sind Referenzen auf der linken und rechten Seite der Operatoren ==
und !=
. Jede Referenz wird an die interne Funktion GetValue()
übergeben, um den entsprechenden Wert zurückzugeben. Der Kern des Abschnitts ==
und !=
wird durch den in Abschnitt 11.9.3:
vergleiche
x == y
, wobeix
undy
Werte sind, was zutrue
oderfalse
führt. Dieser Vergleich wird wie folgt durchgeführt:
- Wenn
Type(x)
identisch ist wieType(y)
, dann
- Wenn
Type(x)
Undefined
ist, returntrue
.- Wenn
Type(x)
Null
ist, returntrue
.- if
Type(x)
istNumber
, dann
- Wenn
x
NaN
ist, returnfalse
.- Wenn
y
NaN
ist, returnfalse
.- Wenn
x
undy
der gleiche numerische Wert sind, returntrue
.- if
x
ist 0 undy
-0, returntrue
.- Wenn
x
-0 undy
0 ist, wirdtrue
zurückgegeben.- return
false
.- Wenn
Type(x)
String
ist, wennx
undy
genau die gleiche Zeichensequenz sind (dieselbe Länge und die gleichen Zeichen in der entsprechenden Position), wirdtrue
zurückgegeben. Ansonsten returnfalse
.- Wenn
Type(x)
Boolean
ist, wennx
undy
beidetrue
oder beidefalse
sind, geben Sietrue
zurück. Ansonsten returnfalse
.- Wenn
x
undy
auf dasselbe Objekt beziehen, geben Sietrue
zurück. Ansonsten returnfalse
.- Wenn
x
null
undy
undefined
ist, dann returntrue
.- Wenn
x
undefined
undy
null
ist, dann returntrue
.- Wenn
Type(x)
Number
undType(y)
String
ist, wird das Ergebnis von Vergleichx == ToNumber(y)
zurückgegeben.- Wenn
Type(x)
String
undType(y)
Number
ist, wird das Ergebnis von VergleichToNumber(x) == y
zurückgegeben.- Wenn
Type(x)
Boolean
ist, wird das Ergebnis von VergleichToNumber(x) == y
zurückgegeben.- Wenn
Type(y)
Boolean
ist, wird das Ergebnis von Vergleichx == ToNumber(y)
zurückgegeben.- Wenn
Type(x)
String
oderNumber
undType(y)
Object
ist, wird das Ergebnis von Vergleichx == ToPrimitive(y)
zurückgegeben.- Wenn
Type(x)
Object
undType(y)
String
oderNumber
ist, wird das Ergebnis von VergleichToPrimitive(x) == y
zurückgegeben.- return
false
.
Schritt 1 Der Operand -Typ ist der gleiche gleich, wenn es in diesem Algorithmus ausgeführt wird. Es zeigt, dass undefined
gleich undefined
und null
gleich null
ist.Es zeigt auch, dass nichts gleich NaN
(nicht nummer), zwei identische Werte gleich sind, 0 entspricht -0, zwei Zeichenfolgen mit derselben Länge und derselben Zeichenfolge gleich, true
gleich true
, false
ist gleich false
und zwei Verweise auf dasselbe Objekt sind gleich. Die Schritte 2 und 3 zeigen, warum null != undefined
false
zurückgibt. JavaScript betrachtet diese Werte als gleich. Ab Schritt 4 wird der Algorithmus interessant. Dieser Schritt konzentriert sich auf die Gleichheit zwischen den Werten Number
und String
. Wenn der erste Operand Number
ist und der zweite Operand String
ist, wird der zweite Operand durch die interne Funktion von ToNumber()
in Number
in x == ToNumber(y)
konvertiert. Der Ausdruck String
bedeutet Rekursion; Schritt 5 entspricht Schritt 4, aber der erste Operand hat einen Typ Number
und muss in einen Typ Number
konvertiert werden. Die Schritte 6 und 7 konvertieren den booleschen Operanden in einen Number
-Typ und rekursiv. Wenn der andere Operand ein Boolescher ist, wird er in Object
in ToPrimitive()
umgewandelt, wenn dieser Algorithmus das nächste Mal ausgeführt wird, was wieder auftritt. Aus Sicht der Leistung möchten Sie möglicherweise sicherstellen, dass beide Operanden Boolesche Typen sind, um zwei rekursive Schritte zu vermeiden. Schritt 9 zeigt, dass der Operand, wenn der Typ eines Operanden false
ist, der Operand durch die interne Funktion ToNumber()
in den ursprünglichen Wert konvertiert wird und der Algorithmus rekursiv ist. Schließlich berücksichtigt der Algorithmus, dass die beiden Operanden nicht gleich sind und in Schritt 10 ToPrimitive()
zurückgegeben werden. Obwohl detailliert, ist der abstrakte Gleichstellungsvergleichsalgorithmus ziemlich leicht zu verstehen. Es verweist jedoch auf ein Paar interne Funktionen ToNumber()
und Number
, deren interne Arbeit ausgesetzt sein muss, um den Algorithmus vollständig zu verstehen. Die
Undefined
ist, return NaN
. Null
ist, return 0. true
ist, return 1. Wenn der Parameter ein boolescher Wert false
ist, senden Sie 0 zurück. Number
ist, wird der Eingabeparameter zurückgegeben - keine Konvertierung. String
ist, wird Abschnitt 9.3.1 "Tonumber vom String -Typ" angewendet. Gibt den Wert zurück, der dem von der Syntax angegebenen String -Parameter entspricht. Wenn der Parameter nicht mit der angegebenen Syntax übereinstimmt, geben Sie NaN
zurück. Zum Beispiel verursacht der Parameter "xyz" die Rückgabe NaN
. Darüber hinaus führt der Parameter "29" zu einer Rückkehr von 29. Object
ist, wenden Sie die folgenden Schritte an: primValue
sein ToPrimitive(输入参数, 提示Number)
. ToNumber(primValue)
. ToPrimitive()
akzeptiert einen Eingabeparameter und einen optionalen PreferredType
Parameter. Die Eingabeparameter werden in den Nicht-Objekt-Typ konvertiert. Wenn das Objekt in mehrere primitive Typen konvertiert werden kann, verwenden Sie ToPrimitive()
die optionale PreferredType
Eingabeaufforderung, um den bevorzugten Typ zu verzerrt. Die Umwandlung erfolgt wie folgt:
Undefined
ist, wird der Eingabeparameter (Undefined
) zurückgegeben - keine Konvertierung. Null
ist, wird der Eingabeparameter (Null
) zurückgegeben - keine Konvertierung. Boolean
ist, geben Sie den Eingabeparameter zurück - keine Konvertierung. Number
ist, geben Sie den Eingabeparameter zurück - keine Konvertierung. String
ist, geben Sie den Eingabeparameter zurück - keine Konvertierung. Object
ist, wird der Standardwert des Eingabeparameters zurückgegeben. Rufen Sie den Standardwert des Objekts ab, indem Sie die interne Methode des Objekts aufrufen und eine optionale [[DefaultValue]]
Eingabeaufforderung übergeben. Das Verhalten von PreferredType
ist in Abschnitt 8.12.8 für alle nativen ECMAScript -Objekte definiert. [[DefaultValue]]
und ==
und allmählich algorithmische Schritte bereitstellen. !=
Verstehe die bösen Zwillinge
Jetzt, da wir verstanden haben, wie und ==
gemäß der ECMascript -Spezifikation funktionieren, nutzen wir dieses Wissen, indem wir die verschiedenen Ausdrücke, an denen diese Betreiber beteiligt sind, untersuchen. Wir werden durch die Bewertung dieser Ausdrücke gehen und herausfinden, warum sie !=
oder true
sind. Betrachten Sie für mein erstes Beispiel die folgenden Ausdruckspaare, die am Anfang des Artikels eingeführt wurden: false
"this_is_true" == false // false "this_is_true" == true // false
typeof "this_is_true"
Gibt "String" zurück, während typeof false
oder typeof true
"boolean" zurückgibt. Boolean
hat. Der Ausdruck wird in "this_is_true" == ToNumber(false)
und "this_is_true" == ToNumber(true)
konvertiert. ToNumber(false)
Gibt 0, ToNumber(true)
zurück 1 zurück, was die Ausdrücke zu "this_is_true" == 0
bzw. "this_is_true" == 1
vereinfacht. Zu diesem Zeitpunkt rekursiv der Algorithmus. String
und der Typ des rechten Operanden Number
beträgt. Der Ausdruck wird in ToNumber("this_is_true") == 0
und ToNumber("this_is_true") == 1
konvertiert. ToNumber("this_is_true")
Gibt NaN
zurück, was die Ausdrücke zu NaN == 0
bzw. NaN == 1
vereinfacht. Zu diesem Zeitpunkt rekursiv der Algorithmus. NaN
, 0 und 1 alle Number
sind. Überspringen Sie die Schritte 1.a und 1.b, die nicht anwendbar sind. Schritt 1.C.I gilt jedoch, da der linke Operand NaN
beträgt. Der Algorithmus gibt nun false
(NaN
nicht gleich etwas, einschließlich sich selbst) als Wert jedes ursprünglichen Ausdrucks zurück und führt den Stapel zurück, um die Rekursion vollständig zu beenden. Mein zweites Beispiel (basierend auf der Erklärung der Bedeutung des Lebens in der "Galaxy Wandering -Handbuch") vergleicht ein Objekt mit einer Zahl nach ==
und gibt true
:
"this_is_true" == false // false "this_is_true" == true // false
Die folgenden Schritte zeigen, wie JavaScript den Abstract Equality -Vergleichsalgorithmus verwendet, um true
als Wert des Ausdrucks zu erhalten:
Object
und der Typ des rechten Operanden Number
beträgt. Der Ausdruck wird in ToPrimitive(lifeAnswer) == 42
konvertiert. ToPrimitive()
rufen Sie die interne Methode lifeAnswer
ohne Eingabeaufforderung auf. Gemäß Abschnitt 8.12.8 der Spezifikation von ECMascript 262 ruft die [[DefaultValue]]
die [[DefaultValue]]
-Methode auf, die "42" zurückgibt. Der Ausdruck wird in toString()
konvertiert und der Algorithmus ist rekursiv. "42" == 42
String
beträgt. Der Ausdruck wird in Number
konvertiert. ToNumber("42") == 42
ToNumber("42")
konvertiert. Der Algorithmus regt und führt Schritt 1.C.III aus. Da die Zahlen gleich sind, wird 42 == 42
rekursiv zurückgegeben und erweitert. true
statt true
:
false
"this_is_true" == false // false "this_is_true" == true // false
zu erhalten. true
'' == 0
ToNumber('') == 0
Stringnumericliteral ::: [leer] MV [mathematischer Wert] 0 beträgt. 0 == 0
Mit anderen Worten, der Wert einer leeren Zeichenfolge ist 0.)
Führen Sie Schritt 1.C.III aus, der 0 mit 0 vergleicht und true
: true
zu erhalten
0 == '0'
0 == ToNumber('0')
0 == 0
Führen Sie Schritt 1.C.III aus, der 0 mit 0 vergleicht und true
zu erhalten. Weil die beiden Saiten unterschiedliche Längen haben (0 und 1), geben Sie true
zurück. '' == '0'
false
Sie fragen sich vielleicht, warum Sie sich die Mühe machen sollten,
und zu verwenden. Immerhin haben frühere Beispiele gezeigt, dass diese Operatoren aufgrund des Typs Guss und Rekursion ==
und !=
und ===
-Operatoren möglicherweise langsamer sein können Möglicherweise möchten Sie !==
und ==
verwenden, da in einigen Fällen keine Vorteile vorhanden sind. Betrachten Sie das folgende Beispiel: !=
"this_is_true" == false // false "this_is_true" == true // false
typeof
gibt einen String
-Werwert zurück. Da der Wert String
mit einem anderen String
-Wergium ("Objekt") verglichen wird, tritt kein Typ -Guss auf und ==
ist so effizient wie ===
. Vielleicht wird ein JavaScript -Neuling, der noch nie auf ===
begegnet ist, solcher Code klarer finden. In ähnlicher Weise erfordert das folgende Code -Snippet kein Typ -Gießen (die Arten von beiden Operanden sind Number
), daher ist !=
so effizient wie !==
:
'' == 0 // true 0 == '0' // true '' == '0' // false
Diese Beispiele zeigen, dass ==
und !=
für Vergleiche geeignet sind, für die kein Gießen erforderlich ist. Wenn Operand -Typen unterschiedlich sind, sind ===
und !==
die besten Entscheidungen, da sie eher false
als unerwartete Werte zurückgeben (z. B. false == ""
Renditen true
). Wenn der Operand -Typ gleich ist, gibt es keinen Grund, ==
und !=
nicht zu verwenden. Vielleicht ist es Zeit, aufzuhören, Angst vor bösen Zwillingen zu haben, und wenn Sie sie verstanden haben, sind sie weniger böse.
FAQs für JavaScript -Gleichstellung und Vergleichsbetreiber (FAQs)
Was ist der Unterschied zwischen==
und ===
in JavaScript? In JavaScript sind ==
und ===
Vergleichsoperatoren. Sie unterscheiden sich jedoch in der Art und Weise, wie sie Werte vergleichen. Der ==
-Operator (auch als loser Gleichheitsoperator bezeichnet) führt vor dem Vergleich Typguss durch. Dies bedeutet, dass JavaScript, wenn Sie zwei verschiedene Werte Arten von Werten vergleichen, vor der Durchführung des Vergleichs versuchen, einen Typ in einen anderen umzuwandeln. Andererseits führt der ===
-Operator (als strengen Gleichstellungsoperator bezeichnet) kein Typ -Casting durch. Es vergleicht gleichzeitig Werte und Typen, was bedeutet, dass JavaScript sie als ungleich betrachtet, wenn die beiden Werttypen unterschiedlich sind.
===
statt ==
verwenden? wird im Allgemeinen empfohlen, in JavaScript ===
statt ==
zu verwenden, da es strengere Vergleiche bietet, was bedeutet, dass es keine Typgüsse und Überprüfungen für Werte und Typen durchführt. Dies kann dazu beitragen, unerwartete Ergebnisse zu vermeiden, wenn verschiedene Wertearten verglichen werden. Bei der Verwendung ==
beispielsweise berücksichtigt JavaScript die Nummer 0 und die leere Zeichenfolge "" gleich, da er den Typ vor dem Vergleich umwandelt. Mit ===
werden sie jedoch als ungleich angesehen, da sie unterschiedliche Typen haben.
In JavaScript gegossenes Typ bezieht sich auf automatisch oder implizit konvertierende Werte von einem Datentyp in einen anderen. Dies geschieht, wenn die Bediener für verschiedene Operandenarten verwendet werden oder wenn ein Typ erforderlich ist. Bei der Verwendung des losen Gleichstellungsoperators (==
) versucht JavaScript beispielsweise, Operanden vor Vergleiche in allgemeine Typen umzuwandeln.
In JavaScript werden Objekte nach Referenz verglichen, nicht nach Wert. Dies bedeutet, dass auch wenn zwei Objekte genau die gleichen Eigenschaften und Werte haben, sie nicht als gleich angesehen werden, da sie sich auf verschiedene Objekte im Speicher beziehen. Der einzige Fall, in dem Objekte als gleich angesehen werden, ist, dass sie sich auf genau dasselbe Objekt beziehen.
Was ist der Unterschied zwischen==
und !=
in JavaScript? ==
und !=
sind Vergleichsoperatoren in JavaScript. Der Operator ==
prüft, ob die Werte der beiden Operanden gleich sind, und führt bei Bedarf Typvergüsse durch. Andererseits prüft der !=
-Operator, ob die Werte der beiden Operanden nicht gleich sind, und führt bei Bedarf Typvergüsse durch.
===
und !==
in JavaScript? ===
und !==
sind Vergleichsoperatoren in JavaScript. Der Operator ===
prüft, ob die Werte der beiden Operanden gleichzeitig die Werte und Typen berücksichtigen. Andererseits prüft der !==
-Operator, ob die Werte der beiden Operanden nicht gleich sind, wobei sowohl die Werte als auch die Typen berücksichtigt werden.
In JavaScript sind Arrays Objekte, verglichen mit Referenz, nicht nach Wert. Dies bedeutet, dass auch wenn zwei Arrays dieselben Elemente in derselben Reihenfolge enthalten, sie nicht als gleich angesehen werden, da sie sich auf verschiedene Objekte im Speicher beziehen. Um zwei Arrays mit ihrem Inhalt zu vergleichen, müssen Sie jedes Element separat vergleichen.
null
und undefined
? In JavaScript werden null
und undefined
als lose gleich (==
) angesehen, da beide fehlende Werte darstellen. Sie sind jedoch nicht gleich gleich (===
), weil sie unterschiedliche Typen sind.
In JavaScript haben Vergleichsbetreiber die gleiche Prioritätsniveau. Sie werden von links nach rechts berechnet. Es ist jedoch wichtig zu beachten, dass sie eine geringere Priorität haben als arithmetische und bitweise Operatoren, jedoch höher als logische Operatoren.
Ja, Sie können Vergleichsoperatoren mit Zeichenfolgen in JavaScript verwenden. JavaScript verwendet die lexikalische (Wörterbuch-) Reihenfolge beim Vergleich von Zeichenfolgen. Es ist jedoch wichtig zu beachten, dass Großbuchstaben als "klein" als Kleinbuchstaben angesehen werden, da sie kleinere ASCII -Werte haben.
Das obige ist der detaillierte Inhalt vonFürchte dich nicht um die bösen Zwillinge - sitepoint. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!