Wie wir alle wissen, ist == in JavaScript eine relativ komplexe Operation. Die Betriebsregeln sind sehr seltsam und können leicht Fehler machen, was es zu einem der "schlimmsten Merkmale" in JavaScript macht.
Basierend auf dem sorgfältigen Lesen der ECMascript -Spezifikation habe ich ein Bild gezeichnet. Ich dachte, nachdem Sie dieses Bild verstanden haben, werden Sie alles über die == Operation gründlich verstehen. Gleichzeitig habe ich versucht, allen durch diesen Artikel zu beweisen, dass == nicht so schlimm ist. Es ist leicht zu meistern und sieht sogar vernünftig und nicht so schlimm aus.
Erstens das Bild:
== Die genaue Beschreibung der Betriebsregeln lautet hier: Der Abstract Equality -Vergleichsalgorithmus. Sind Sie mit einer so komplizierten Beschreibung sicher, dass Sie sich nach dem Lesen nicht schwindelig fühlen? Können Sie es verwenden, um Ihre Praxis sofort zu führen?
Es funktioniert sicher nicht. Schließlich gilt die Spezifikation für Entwickler von JavaScript -laufender Umgebung (im Vergleich zu Entwicklern von V8 -Motoren), nicht für Nutzer von Sprachen. Das obige Bild übersetzt die Spezifikation in ein Formular, das für alle bequem zu sehen ist.
Bevor Sie jeden Teil in Abbildung 1 ausführlich vorstellen, überprüfen wir das Wissen über Typen in JS:
Es gibt zwei Arten von Werten in JS: Basistyp und Objekttyp.
Zu den Grundtypen gehören: undefined, Null, Boolean, Nummer und String.
Sowohl der undefinierte Typ als auch der Null -Typ haben nur einen Wert, nämlich undefiniert und Null; Der Boolesche Typ hat zwei Werte: Richtig und falsch; Es gibt viele Werte des Zahlentyps; und der String -Typ hat unzählige Werte (theoretisch).
Alle Objekte haben ValueOF () und toString () -Methoden, die von Objekt geerbt werden und natürlich durch Unterklassen neu geschrieben werden können.
Betrachten Sie nun den Ausdruck:
x == y
wobei x und y Werte eines der sechs Typen sind.
Wenn die Arten von x und y gleich sind, kann x == y in x === y konvertiert werden und letzteres ist sehr einfach (das einzige, was zu beachten ist Nan). Im Folgenden werden wir nur die Fälle betrachten, in denen die Arten von x und y unterschiedlich sind.
1. haben und keine
In Abbildung 1 werden sechs Arten von JavaScript -Werten durch Rechtecke mit blauem Hintergrund dargestellt. Zuerst sind sie in zwei Gruppen unterteilt:
Zeichenfolge, Anzahl, Boolescher und Objekt (entsprechend der großen rechteckigen Box links)
Undefiniert und null (entsprechend der rechteckigen Kiste rechts)
Was ist die Grundlage für die Gruppierung? Schauen wir uns an. Undefinierte und null auf der rechten Seite werden verwendet, um nicht oder leer Unsicherheiten anzuzeigen, während die vier Typen rechts bestimmt, vorhanden und nicht leer sind. Wir können das sagen:
Links befindet sich eine Welt der Existenz und rechts eine leere Welt.
Daher ist es vernünftig, einen Wert in den beiden Welten mit Falsch zu vergleichen. (d. H. Die horizontale Linie, die zwei Rechtecke in Abbildung 1 verbindet, ist falsch gekennzeichnet)
2. leer und leer
Undefiniert und Null in JavaScript sind ein weiterer Ort, der uns oft abstürzt. Es wird normalerweise als Designfehler angesehen, in den wir nicht graben werden. Aber ich habe gehört, dass der Autor von JavaScript anfänglich dachte:
Wenn Sie vorhaben, dem Wert des Objekttyps eine Variable zuzuweisen, aber noch keinen Wert zugewiesen haben, können Sie Null verwenden, um den Status zu diesem Zeitpunkt darzustellen (einer der Beweise ist, dass das Ergebnis von Typ von null "Objekt" ist). Wenn Sie im Gegenteil vorhaben, dem Wert des ursprünglichen Typs eine Variable zuzuweisen, aber noch keinen Wert zugewiesen haben, können Sie undefined zu diesem Zeitpunkt und definiert den Status darstellen.
Unabhängig davon, ob dieses Gerücht glaubwürdig ist oder nicht, ist es vernünftig, dass das Ergebnis des Vergleichs zwischen beiden wahr ist. (d. H. Richtig auf der vertikalen Linie rechts in Abbildung 1 markiert)
Bevor Sie mit dem nächsten Schritt übergehen, sprechen wir über die beiden Symbole in Abbildung 1: Großbuchstaben N und P. Diese beiden Symbole bedeuten im PN -Abschnitt nicht positiv und negativ. Stattdessen:
N repräsentiert den Tonumber Operation, was bedeutet, dass der Operand in eine Zahl umgewandelt wird. Es handelt sich um eine abstrakte Operation in der ES -Spezifikation, aber wir können die Number () -Funktion in JS verwenden, um sie äquivalent zu ersetzen.
P repräsentiert den TopRimitive -Operation, dh den Operanden in den Wert des ursprünglichen Typs. Es ist auch eine abstrakte Operation in der ES -Spezifikation und kann auch in den äquivalenten JS -Code übersetzt werden. Aber es ist etwas komplizierter. Einfach ausgedrückt, für ein Objekt obj:
TopRimitive (OBJ) entspricht: zuerst berechnen obj.valueof (), wenn das Ergebnis der ursprüngliche Wert ist, wird dieses Ergebnis zurückgegeben. Andernfalls wird obj.tostring () berechnet, und wenn das Ergebnis der ursprüngliche Wert ist, wird dieses Ergebnis zurückgegeben. Ansonsten wird eine Ausnahme geworfen.
Hinweis: Hier gibt es eine Ausnahme, dh ein Objekt vom Typ vom Typ, das zuerst die Methode toString () aufruft.
In Abbildung 1 zeigt eine mit N oder P gekennzeichnete Linie an, dass die Operanden auf der Seite, die N oder P markiert ist, zuerst die Tonumum- oder Toprimitive -Transformation durchführen muss, wenn die beiden Datentypen angeschlossen sind, um den Operand auf der Seite zu markieren.
3.. Richtig und falsch
Wie aus Abbildung 1 ersichtlich ist, wird der Boolesche Wert in eine Zahl konvertiert, wenn ein Boolescher Wert mit anderen Wertenarten verglichen wird. Speziell
Richtig -> 1
Falsch -> 0
Dies erfordert überhaupt nicht zu viel verbaler Missbrauch. Denken Sie darüber nach, in C gibt es überhaupt keinen Booleschen Typ. Die Ganzzahlen 1 und 0 werden normalerweise verwendet, um die wahre oder falsche Logik darzustellen.
Iv. Zeichenfolge
In Abbildung 1 teilen wir Zeichenfolge und Anzahl in eine Gruppe. Warum? Unter den sechs Typen sind String und Anzahl Sequenzen von Zeichen (zumindest wörtlich). Eine Zeichenfolge ist eine Sequenz aller rechtlichen Zeichen, während eine Zahl als eine Abfolge von Zeichen angesehen werden kann, die bestimmte Bedingungen erfüllen. Daher können Zahlen als Teilmenge von Zeichenfolgen angesehen werden.
Nach Abbildung 1 müssen Sie bei der Durchführung des == -Betriebs von Zeichenfolgen und Zahlen den Tonumber Operation verwenden, um die Zeichenfolge in Zahlen umzuwandeln. Angenommen, X ist eine Zeichenfolge und y ist eine Zahl, dann: dann:
x == y -> nummer (x) == y
Wie lautet die Regel für die Umwandlung von Zeichenfolgen in Zahlen? Die Spezifikation wird sehr kompliziert beschrieben, aber im Allgemeinen sollen die Zitate auf beiden Seiten der Zeichenfolge entfernt werden und feststellen, ob sie eine rechtliche Nummer bilden kann. Wenn ja, ist das Konvertierungsergebnis diese Zahl; Ansonsten ist das Ergebnis Nan. Zum Beispiel:
Nummer ('123') // Ergebnis 123
Nummer ('1.2e3') // Ergebnis 1200
Nummer ('123abc') // Ergebnis Nan
Natürlich gibt es Ausnahmen, wie das Ergebnis der Umwandlung einer leeren Zeichenfolge in eine Zahl 0. Im Moment ist
Nummer ('') // Ergebnis 0
V. Einfach und komplex
Primitive Typen sind einfache Typen, sie sind unkompliziert und leicht zu verstehen. Der Nachteil ist jedoch, dass die Expressionsfähigkeit begrenzt und schwer zu erweitern ist, sodass es Objekte gibt. Ein Objekt ist eine Sammlung von Attributen, und das Attribut selbst kann ein Objekt sein. Daher können Objekte willkürlich komplex ausreichend konstruiert werden, um verschiedene Dinge darzustellen.
Aber manchmal sind die Dinge kompliziert und keine gute Sache. Zum Beispiel hat nicht jeder Zeit, Geduld oder die Notwendigkeit, es von Anfang bis Ende zu lesen. Normalerweise reicht es aus, nur seine zentralen Gedanken zu verstehen. Das Papier verfügt also über Schlüsselwörter und Übersichten. Gleiches gilt für Objekte in JavaScript. Wir müssen ein Mittel haben, um seine Hauptmerkmale zu verstehen, damit die Objekte Methoden () und ValueOf () haben.
Die Methode toString () wird verwendet, um eine Textbeschreibung des Objekts zu erhalten. und die ValueOf () -Methode wird verwendet, um den Eigenwert des Objekts zu erhalten.
Natürlich ist dies nur mein eigenes Verständnis. Wie der Name schon sagt, gibt die Methode toString () eine Zeichenfolge zurück. Was ist mit der ValueOf () -Methode? Gemäß der Beschreibung in der Spezifikation neigt es dazu, eine Zahl zurückzugeben - obwohl im integrierten Typ die ValueOF () -Methode nur Nummer und Datum zurückgibt.
Nach Abbildung 1 muss das Objekt, wenn ein Objekt mit einem Nicht-Objekt verglichen wird, in einen primitiven Typ umgewandelt werden (obwohl beim Vergleich mit einem booleschen Typ der Boolesche Typ zuerst in einen numerischen Typ konvertiert werden muss, der Objekttyp jedoch als nächstes in einen primitiven Typ konvertiert werden muss). Dies ist auch vernünftig. Immerhin ist == nicht streng gleichvergleich. Wir müssen nur die Hauptmerkmale des Objekts herausnehmen, um an der Operation teilzunehmen, und die sekundären Merkmale beiseite legen.
Sechs. Alles wird gezählt
Lassen Sie uns zurückblicken. Wenn wir die Pfeile in diesen Zeilen markieren, werden die Verbindung von am Ende von N oder P bis zum anderen Ende markiert, dann werden wir (nicht in Betracht ziehen und nicht definiert und Null in Betracht ziehen):
Hast du etwas entdeckt? Ja, während des Berechnungsprozesses neigen alle Arten von Werten dazu, auf numerische Typen umzuwandeln. Immerhin sagte eine Berühmtheit einmal:
Alles wird gezählt.
7. Gib mir einfach eine Kastanie
In der Vergangenheit gibt es zu viel Unsinn. Hier ist ein Beispiel, um zu beweisen, dass Abbildung 1 in der Tat bequem und effektiv ist, um die Praxis zu leiten.
Beispiel berechnen Sie Folgendes:
[''] == falsch
Erstens sind die beiden Operanden Objekttyp bzw. Booleschen Typ. Nach Abbildung 1 ist es notwendig, den booleschen Typ in einen numerischen Typ umzuwandeln, und das Ergebnis der Umwandlung von Falsch in einen Numarer ist 0, so dass der Ausdruck:
[''] == 0
Die beiden Operanden werden Objekttyp und numerische Typ. Gemäß Abbildung 1 muss der Objekttyp in den ursprünglichen Typ konvertiert werden:
Rufen Sie zuerst [] .Valueof () an. Da die ValueOf () -Methode des Arrays selbst zurückgibt, ist das Ergebnis nicht der ursprüngliche Typ. Rufen Sie weiter [] .ToString () an.
Für Arrays besteht der Algorithmus der toString () -Methode darin, jedes Element in einen String -Typ zu konvertieren und dann nacheinander zu verkettet, sodass das Endergebnis eine leere Zeichenfolge ist, die ein Wert des ursprünglichen Typs ist.
An diesem Punkt wird der Ausdruck:
'' == 0
Die beiden Operanden werden an Zeichenstypen und numerischen Typen. Gemäß Abbildung 1 muss der String -Typ in numerische Typen konvertiert werden. Wie bereits erwähnt, wird die leere Zeichenfolge zu einer Anzahl von 0. Daher wird der Ausdruck:
0 == 0
Bisher sind die Arten der beiden Operanden endlich gleich, und das Ergebnis ist offensichtlich wahr.
Aus diesem Beispiel können wir sehen, dass wir, um die Regeln von == Operation zu beherrschen, zusätzlich zu Abbildung 1 auch an die Regeln der Methoden toString () und valueOf () dieser eingebauten Objekte erinnern müssen. Einschließlich Objekt, Array, Datum, Nummer, String, Boolean usw.
8. Lassen Sie uns zusammenfassen
Die vorherige Aussage ist sehr verwirrend. Hier werde ich die Regeln der in Abbildung 1 ausgedrückten Operation zusammenfassen:
Das Ergebnis von undefined == NULL ist wahr. Das Ergebnis ihres Vergleichs mit allen anderen Werten ist falsch.
Wenn eine String == -Nummer, wird die Zeichenfolge in eine Zahl konvertiert.
Boolescher Wert == Wenn andere Typen verwendet werden, wird der Boolesche Wert in eine Zahl konvertiert.
Wenn ein Objekt == numerisch/String, wird das Objekt in einen primitiven Typ konvertiert.
Schließlich habe ich das Bild nur für Unterhaltung geändert :)
OK, es ist vorbei. Wenn Sie der Meinung sind, dass dieser Artikel für Sie nützlich ist, mögen Sie ihn bitte, damit mehr Menschen ihn sehen können.
Bitte weisen Sie bitte auf die Irrtümer des Artikels hin.