Ich habe heute mit Arrays in Javascript herumgespielt und dieses kleine Juwel bemerkt:
%Vor%Es kommt mir ziemlich seltsam vor, dass das Array nicht mit sich selbst übereinstimmt.
Aber dann bemerkte ich das, was noch seltsamer war:
%Vor%?!?!?!? !!!?
Warum in der Welt ist [1, 2, 3]
nicht ==
für sich selbst, aber ist ==
für die Zeichenkette?
Mir ist klar, dass ==
nicht gleich wie ===
ist. Trotzdem, welche Bosheit könnte Mr. Javas seltsame Dinge verursachen?
Ok, also zuerst müssen Sie verstehen, wie JavaScript Werte in Ihrem Programm behandelt. Alle von Ihnen erstellten Variablen werden lediglich Referenzen an einen Speicherort im Speicher sein, an dem das Objekt gespeichert ist. Daher, wenn Sie dies tun:
%Vor%... es macht drei Dinge:
Sie können auf etwas vernünftiges Verhalten prüfen, indem Sie diesen Code ausführen:
%Vor%Nun zu Ihrer Frage zu der Zeichenfolge
Wenn Sie den Operator ==
verwenden, versucht er, die beiden Operanden in den gleichen Typ zu konvertieren (böses Verhalten ... ich weiß ...)
Wenn es dies tut, entscheidet es, beide in eine Zeichenkette zu konvertieren, bevor es den Vergleich durchführt (das Ergebnis ist also wirklich "1,2,3" === "1,2,3"
, was zu true führt.
Ich kann Ihnen kein vollständiges Bild geben, da es nur wenige Menschen gibt, die jede Nuance des Wahnsinns verstehen, der JavaScript ist, aber hoffentlich wird dadurch etwas Nebel beseitigt.
Für den ersten Teil erstellen Sie zwei verschiedene Objekte, da Arrays nur Objekte sind und da Sie zwei davon erstellt haben, sind beide eindeutig.
==
operator[..] Wenn einer der beiden Operanden eine Zeichenfolge ist, wird der andere Operand möglichst in eine Zeichenfolge konvertiert. [..] Wenn beide Operanden Objekte sind, vergleicht JavaScript interne Referenzen, die gleich sind, wenn sich Operanden auf dasselbe Objekt im Speicher beziehen.
Das heißt, dass [1, 2, 3]
in eine Zeichenkette umgewandelt wird, die gleich "1,2,3"
ist. Ein Array-Objekt ist jedoch keinem anderen Array-Objekt gleich.
Der erste Vergleich schlägt fehl, weil bei einem grundlegenden Vergleich zweier Objekte überprüft wird, ob es sich um das gleiche referenzierte Objekt handelt, und nicht, wenn die beiden Objekte die gleichen Werte haben. Wenn Sie zwei Arrays vergleichen möchten, müssen Sie die Werte durchlaufen.
%Vor%Denken Sie daran, dass dies kein rekursiver Vergleich ist, so dass er nur für ein Array primitiver Werte funktioniert.
Der zweite Vergleich funktioniert, weil == versucht, die Typen der Argumente zu erzwingen, und wenn Sie ein Array in einen String konvertieren, ist das das Ergebnis.
%Vor% Die beiden Array
-Objekte sind verschieden und daher bei Verwendung des Vergleichs ==
nicht gleich. Um sie zu vergleichen, müssten Sie eine Schleife erstellen, wobei der Index in beiden identisch ist (und rekursiv, wenn die Elemente auch Array
s oder Object
s sind).
Der zweite Grund ist, dass Array
implizit seinen toString()
aufgerufen hat, der '1,2,3'
zurückgegeben hat (try it).
Dies liegt daran, dass nach den Regeln eines Vergleichs von ==
(nicht streng) in ECMAScript der linke Operator zu einem String
gezwungen wurde ( ==
führt eine Konvertierung durch).
Weil ==
nur dann erzwingt, wenn es ist, den gleichen Typ zu erhalten (z. B. nur, wenn die Typen der Operanden unterschiedlich sind). Wenn Sie
... kein Zwang ist erforderlich; beides sind Objekte. Sie sind nicht das selbe Objekt, also ist es false
. Leute denken an ==
als den "erzwingenden" Gleichheitsoperator, und das ist es, aber der Schlüssel ist, dass es nur dann erzwingt, wenn es ist.
Aber tun
%Vor% ... beinhaltet Operanden von verschiedenen Typen: String und Objekt. So ist Zwang getan. In diesem Fall wird das Objekt wie in String(obj)
zum String gezwungen, was sein Standardverhalten toString
aufruft, was für Arrays .join()
ist. join
wird standardmäßig auf ","
als Trennzeichen gesetzt, sodass die resultierende Zeichenfolge mit "1,2,3"
übereinstimmt. (Sie finden die vollständige Logik, warum das Objekt gezwungen wird, in der Spezifikation zu stringeln. )
Tags und Links javascript