Über hier habe ich den Ratschlag gefunden, dass es am besten ist zu verwenden Nicht-Typ-Zwangsstring-Vergleich, aber in Chrome entdeckte ich etwas seltsam:
%Vor%Ist das Standardverhalten? Wenn ja, welche Art von t1 und t2 gibt es? Danke.
String
, aufgerufen als Funktion, konvertiert sein Argument in ein string
. String
, als Konstruktor bezeichnet, erstellt ein Objekt, dessen Prototyp die Funktion String
ist. (Überprüfen Sie die James-Antwort für den entsprechenden ECMAScript-Spezifikationsabschnitt.)
Das ist in der Tat verwirrend.
Die zwei Gleichheitsoperatoren machen tatsächlich sehr unterschiedliche Dinge. Aus dem Dokument ECMA-262, v 5.1 , macht ===
:
- Wenn
Type(x)
sich vonType(y)
unterscheidet, geben Siefalse
zurück.- Wenn
Type(x)
Undefined
ist, geben Sietrue
zurück.- Wenn
zurückType(x)
Null
ist, geben Sietrue
.- Wenn
Type(x)
Number
ist, dann
ein. Wennx
istNaN
, gibfalse
zurück.
b. Wenny
istNaN
, gibfalse
zurück.
c. Wennx
der gleicheNumber
-Wert ist wiey
, geben Sietrue
zurück.
d. Wennx
ist+0
undy
ist-0
, geben Sietrue
zurück.
e. Wennx
ist-0
undy
ist+0
, geben Sietrue
zurück.
f. Rückgabefalse
.- Wenn
zurückType(x)
String
ist, dann gebetrue
zurück, wennx
undy
genau die gleiche Zeichenfolge sind (gleiche Länge und gleiche Zeichen in den entsprechenden Positionen); Andernfalls geben Siefalse
.- Wenn
zurückType(x)
Boolean
ist, geben Sietrue
zurück, wennx
undy
beidetrue
oder beidefalse
sind; Andernfalls geben Siefalse
.- Gibt
zurücktrue
zurück, wenn sichx
undy
auf dasselbe Objekt beziehen. Andernfalls gibfalse
.
Während ==
tut:
- Wenn
zurückType(x)
dasselbe ist wieType(y)
, dann
ein. WennType(x)
istUndefined
, gibtrue
zurück.
b. WennType(x)
istNull
, gibtrue
zurück.
c. WennType(x)
Number
ist, dann
ich. Wennx
istNaN
, gibfalse
zurück.
ii. Wenny
istNaN
, gibfalse
zurück.
iii. Wennx
der gleicheNumber
-Wert ist wiey
, geben Sietrue
zurück.
iv. Wennx
ist+0
undy
ist-0
, geben Sietrue
zurück.
v. Wennx
ist-0
undy
ist+0
, geben Sietrue
zurück.
vi. Rückgabefalse
.
d. WennType(x)
String
ist, dann gebetrue
zurück, wennx
undy
genau die gleiche Zeichenfolge haben (gleiche Länge und gleiche Zeichen in den entsprechenden Positionen). Andernfalls gibfalse
zurück.
e. WennType(x)
istBoolean
, geben Sietrue
zurück, wennx
undy
beidetrue
oder beidefalse
sind. Andernfalls gibfalse
zurück.
f. Gibttrue
zurück, wenn sichx
undy
auf dasselbe Objekt beziehen. Andernfalls gibfalse
.- Wenn
x
null ist undy
nicht definiert ist, geben Sietrue
zurück.- Wenn
x
nicht definiert ist undy
null ist, geben Sietrue
zurück.- Wenn
Type(x)
istNumber
undType(y)
istString
, geben Sie das Ergebnis des Vergleichs
x == ToNumber(y)
zurück.- Wenn
Type(x)
istString
undType(y)
istNumber
, geben Sie das Ergebnis des Vergleichs
ToNumber(x) == y
zurück.- Wenn
Type(x)
istBoolean
, gebe das Ergebnis des VergleichsToNumber(x) == y
zurück.- Wenn
Type(y)
istBoolean
, gebe das Ergebnis des Vergleichsx == ToNumber(y)
zurück.- Wenn
Type(x)
entwederString
oderNumber
undType(y)
istObject
, geben Sie das Ergebnis des Vergleichsx == ToPrimitive(y)
zurück.- Wenn
Type(x)
istObject
undType(y)
ist entwederString
oderNumber
, geben Sie das Ergebnis des VergleichsToPrimitive(x) == y
zurück.- Gibt
false
zurück.
Beachten Sie, dass in der Spezifikation das Type
eines primitiven Zeichenfolgenobjekts String
ist, während der Typ eines Objekts (einschließlich des String
-Objekts) Object
ist.
Bei ===
ist die relevante Zeile #1
: Die Type
der Objekte sind unterschiedlich, daher wird false
zurückgegeben.
Bei ==
ist die relevante Zeile #8
: x
ist ein String
( "Hello world!"
) und y
ist ein Object
(Das String
-Objekt enthält die Zeichenkette "Hello world!"
) . Somit wird der Vergleich x == ToPrimitive(y)
gemacht. ToPrimitive
endet mit dem Aufruf der Methode valueOf
des Objekts oder, falls diese Methode nicht existiert, der Methode toString
. In diesem Fall gibt die Methode String
von valueOf
-Objekt das Grundelement string
zurück, das das Objekt enthält. Daher wird die Gleichheitsoperation erneut ausgeführt, diesmal zwischen zwei Grundelementen string
s, die denselben Text enthalten, der true
dank #1.d
zurückgibt.
JavaScript ist ein bisschen unordentlich unter der Haube ...
BEARBEITEN: Beachten Sie, dass beim Vergleich von zwei Objekten keine Konvertierungen vorgenommen werden, sondern die Regel #1.f
. Dank der Spezifikation konnte ich die Ausgabe des folgenden Codes korrekt vorhersagen:
EDIT: Nur gedacht, ich würde hinzufügen, dass diese Unterschiede noch mehr durch implizite Typumwandlung verwischt werden. Zum Beispiel funktioniert das Folgende:
%Vor% Das liegt aber nicht daran, dass "hi"
ein Objekt ist (wie in Python):
Sondern weil .
operator führt eine Konvertierung vom Primitiven durch string
type zum String Object
type (erzeugt ein neues String-Objekt), dessen toString
-Methode dann aufgerufen wird.
Wenn Sie das Schlüsselwort " new
" nicht mit String verwenden, erhalten Sie eine primitive Zeichenfolge.
Wenn Sie das Schlüsselwort " new
" verwenden, erhalten Sie ein String-Objekt anstelle eines Primitivs.
Wenn Sie ==
verwenden, wird versucht, in einen vergleichbaren Typ zu konvertieren, damit er gleich sein kann.
Wenn Sie ===
verwenden, wird es nicht konvertiert, sodass ein Objekt nicht einem Primitiv entsprechen kann.
Dieses Verhalten wird in der ECMAScript 5-Spezifikation 15.5.1 und 15.5.2 erläutert:
Wenn
String
als Funktion und nicht als Konstruktor aufgerufen wird, führt es eine Typkonvertierung durch....
Gibt einen String-Wert (nicht ein
String
-Objekt) zurück, der vonToString(value)
berechnet wurde. Wennvalue
nicht angegeben wird, wird die leere Zeichenfolge "" zurückgegeben.
So String("some string")
erstellt einen String-Wert.
Wenn
String
als Teil einesnew
-Ausdrucks aufgerufen wird, handelt es sich um einen Konstruktor: Er initialisiert das neu erstellte Objekt.
So erstellt new String("some string")
eine Instanz des Objekts String
.
Und um Ihre Fragen zu beantworten:
Ist das Standardverhalten?
Ja , aus den oben genannten Gründen.
Wenn ja, was sind die jeweiligen Typen von t1 und t2
?
Sie können dies mit dem Operator typeof
überprüfen:
Dies geschieht, weil der Operator ==
nur prüft, ob die Werte identisch sind, während ===
sowohl den Wert als auch den -Typ überprüft. new String("Hello world!")
erhält nicht den Typ string
, es ist ein object
, während String("Hello world!")
eigentlich ein string
ist.
Tags und Links javascript