5647 Stimmen

Welcher Gleichheitsoperator (== vs ===) sollte in JavaScript-Vergleichen verwendet werden?

Ich benutze JSLint durch JavaScript zu gehen, und es werden viele Vorschläge zum Ersetzen von == (zwei Gleichheitszeichen) mit === (drei Gleichheitszeichen), wenn Sie z. B. Folgendes vergleichen idSele_UNVEHtype.value.length == 0 innerhalb eines if Erklärung.

Gibt es einen Leistungsvorteil durch den Austausch von == con === ?

Da es viele Vergleichsoperatoren gibt, wäre jede Leistungsverbesserung zu begrüßen.

Wenn keine Typkonvertierung stattfindet, gibt es dann einen Leistungsgewinn gegenüber == ?

7173voto

Bill the Lizard Punkte 384619

Der strenge Gleichheitsoperator ( === ) verhält sich identisch mit dem abstrakten Gleichheitsoperator ( == ), außer dass keine Typumwandlung stattfindet und die Typen gleich sein müssen, um als gleich zu gelten.

Referenz: Javascript-Tutorial: Vergleichsoperatoren

Le site == Operator vergleicht auf Gleichheit nach der Durchführung aller erforderlichen Typkonvertierungen . Die === Betreiber wird ノット die Umwandlung vornehmen, wenn also zwei Werte nicht vom gleichen Typ sind === wird einfach zurückgegeben false . Beide sind gleich schnell.

Um Douglas Crockfords ausgezeichnetes Buch zu zitieren JavaScript: Die guten Seiten ,

JavaScript hat zwei Sätze von Gleichheitsoperatoren: === y !== und ihre bösen Zwillinge == y != . Die guten funktionieren so, wie man es erwarten würde. Wenn die beiden Operanden vom gleichen Typ sind und den gleichen Wert haben, dann === produziert true y !== produziert false . Die bösen Zwillinge tun das Richtige, wenn die Operanden vom gleichen Typ sind, aber wenn sie von unterschiedlichem Typ sind, versuchen sie, die Werte zu erzwingen. die Regeln, nach denen sie das tun, sind kompliziert und nicht einprägsam. Dies sind einige der interessanten Fälle:

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

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

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

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

Equality Comparison Table

Der Mangel an Transitivität ist alarmierend. Mein Rat ist, niemals die bösen Zwillinge zu verwenden. Verwenden Sie stattdessen immer === y !== . Alle soeben gezeigten Vergleiche ergeben false avec le === Betreiber.


Aktualisierung:

Ein gutes Argument wurde vorgebracht von @Casebash in den Kommentaren und in @Phillipe Laybaert's Antwort über Gegenstände. Für Objekte, == y === im Einklang miteinander handeln (außer in einem besonderen Fall).

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

Ein Sonderfall liegt vor, wenn Sie ein Primitiv mit einem Objekt vergleichen, das auf dasselbe Primitiv ausgewertet wird, und zwar aufgrund seiner toString o valueOf Methode. Betrachten wir zum Beispiel den Vergleich eines String-Primitivs mit einem String-Objekt, das mit der Methode String Konstrukteur.

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

Hier wird die == Operator prüft die Werte der beiden Objekte und gibt true aber die === ist, zu erkennen, dass sie nicht vom gleichen Typ sind und die false . Welche ist richtig? Das hängt wirklich davon ab, was Sie zu vergleichen versuchen. Ich würde Ihnen raten, die Frage ganz zu umgehen und einfach nicht die String Konstruktor, um String-Objekte aus String-Literalen zu erzeugen.

Referenz
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

14 Stimmen

Ich möchte auch darauf hinweisen, dass 0 === -0 und NaN !== NaN ist, was manchmal verwirrend sein kann. Wenn Sie ±0 differenzieren und NaNs als gleichwertig betrachten wollen, verwenden Sie Object.is (ES2015)

19 Stimmen

Softtyping ist eine Funktion . Offensichtlich weist Crockford auf einige "Artefakte" der Designentscheidung hin, aber die weiche Schreibweise ist immer noch eine Funktion. Wenn sie richtig eingesetzt wird, ist sie absolut in Ordnung zu verwenden. Schütten Sie das Kind nicht mit dem Bade aus.

1 Stimmen

Warum sollten Sie jemals die -0 ?

1253voto

Andreas Grech Punkte 102197

Die Verwendung des == Betreiber ( Gleichstellung )

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

Die Verwendung des === Betreiber ( Identität )

true === 1; //false
"2" === 2;  //false

Dies liegt daran, dass die Gleichheitsoperator == macht Typenzwang , was bedeutet, dass der Interpreter implizit versucht, die Werte vor dem Vergleich umzuwandeln.

Auf der anderen Seite ist die Identitätsoperator === führt keine Typenzwangskontrolle durch und konvertiert die Werte beim Vergleich nicht und ist daher schneller (wie nach Dieser JS-Benchmark Test), da er einen Schritt überspringt.

5 Stimmen

Ich glaube nicht, dass Identität ist hier der richtige Begriff/ === prüft Gleichheit und Typ (genannt Streng ). Idendität bezieht sich in der Regel auf die "Gleichartigkeit", die durch die Object.is Funktion (wie in ES2015).

893voto

SNag Punkte 16571

Hier ist eine interessante Visualisierung des Gleichheitsvergleichs zwischen == y === .

Quelle: https://github.com/dorey/JavaScript-Equality-Table ( Demo , einheitliche Darstellung )


var1 === var2

Bei der Verwendung von === für die JavaScript-Gleichheitsprüfung ist alles so, wie es ist.
Nichts wird umgewandelt, bevor es ausgewertet wird.

Equality evaluation of === in JS

var1 == var2

Bei der Verwendung von == für JavaScript-Gleichheitstests, einige tolle Umbauten stattfinden.

Equality evaluation of == in JS

Zusammenfassung der Gleichstellung in Javascript

Equality in Javascript


Schlussfolgerung:

Verwenden Sie immer === wenn Sie das Thema nicht vollständig verstehen. tolle Umbauten die sich mit == .

10 Stimmen

Eine bessere '=='-Tabelle: algassert.com/visualization/2014/03/27/

0 Stimmen

Zumindest sind == Vergleiche kommutativ (d. h. (a==b) === (b==a)) XD

0 Stimmen

@imkzh Beziehungen werden allgemeiner als symmetrisch statt kommutativ . Aber was ich eigentlich sagen wollte, war: == ist nicht transitiv! (auch wenn man ignoriert NaN )

659voto

Philippe Leybaert Punkte 161931

In den Antworten hier habe ich nichts darüber gelesen, was gleich bedeutet. Einige werden sagen, dass === bedeutet gleich und vom gleichen Typ aber das ist nicht wirklich wahr. Es bedeutet eigentlich, dass beide Operanden verweisen auf das gleiche Objekt oder im Falle von Werttypen, haben denselben Wert .

Nehmen wir also den folgenden Code:

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Das gilt auch hier:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Oder sogar:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Dieses Verhalten ist nicht immer offensichtlich. Es geht um mehr als nur darum, gleich zu sein und zum gleichen Typ zu gehören.

Die Regel lautet:

Für Werttypen (Zahlen):
a === b gibt true zurück, wenn a y b den gleichen Wert haben und vom gleichen Typ sind

Für Referenztypen:
a === b gibt true zurück, wenn a y b auf genau dasselbe Objekt verweisen

Für Streicher:
a === b gibt true zurück, wenn a y b sind beide Zeichenketten und enthalten genau dieselben Zeichen


Strings: der Sonderfall...

Zeichenketten sind keine Werttypen, aber in Javascript verhalten sie sich wie Werttypen, so dass sie "gleich" sind, wenn die Zeichen in der Zeichenkette die gleichen sind und wenn sie die gleiche Länge haben (wie in der dritten Regel erklärt)

Jetzt wird es interessant:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

Aber wie wäre es damit?:

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

Ich dachte, Zeichenketten verhalten sich wie Werttypen? Nun, das hängt davon ab, wen Sie fragen... In diesem Fall sind a und b nicht derselbe Typ. a ist vom Typ Object , während b ist vom Typ string . Denken Sie daran, dass das Erstellen eines String-Objekts mit der String Konstruktor erzeugt etwas vom Typ Object die sich wie eine Zeichenkette verhält die meiste Zeit .

0 Stimmen

Ich habe gerade mit TypeScript heute aus asm/C/C++ begonnen, und dies war eine SEHR hilfreiche Antwort. Danke Philippe!

288voto

nalply Punkte 23497

Lassen Sie mich diesen Ratschlag hinzufügen:

Im Zweifelsfall lesen Sie bitte die Spezifikation !

ECMA-262 ist die Spezifikation für eine Skriptsprache, von der JavaScript ein Dialekt ist. In der Praxis kommt es natürlich mehr darauf an, wie sich die wichtigsten Browser verhalten, als auf eine esoterische Definition, wie etwas gehandhabt werden soll. Aber es ist hilfreich zu verstehen, warum new String("a") !== "a" .

Bitte lassen Sie mich erklären, wie man die Spezifikation liest, um diese Frage zu klären. Ich sehe, dass in diesem sehr alten Thema niemand eine Antwort auf diesen sehr seltsamen Effekt hatte. Wenn Sie also eine Spezifikation lesen können, wird Ihnen das in Ihrem Beruf ungemein helfen. Das ist eine erworbene Fähigkeit. Also, machen wir weiter.

Die Suche in der PDF-Datei nach === bringt mich auf Seite 56 der Spezifikation: 11.9.4. Der strenge Gleichheitsoperator ( === ) und nachdem ich mich durch den Fachjargon gewühlt habe, finde ich:

11.9.6 Der Algorithmus für den strikten Gleichheitsvergleich
Der Vergleich x === y, wobei x und y Werte sind, ergibt wahr o falso . Ein solcher Vergleich wird wie folgt durchgeführt:
  1. Wenn Typ(x) von Typ(y) verschieden ist, wird zurückgegeben falso .
  2. Wenn Type(x) Undefined ist, wird zurückgegeben wahr .
  3. Wenn Type(x) Null ist, wird zurückgegeben wahr .
  4. Wenn Typ(x) nicht Zahl ist, gehen Sie zu Schritt 11.
  5. Wenn x ist NaN Rückkehr falso .
  6. Wenn y NaN Rückkehr falso .
  7. Wenn x der gleiche Zahlenwert wie y ist, wird zurückgegeben wahr .
  8. Wenn x gleich +0 und y gleich 0 ist, wird wahr .
  9. Wenn x gleich 0 und y gleich +0 ist, wird wahr .
  10. Rückgabe falso .
  11. Wenn Type(x) String ist, dann wird wahr wenn x und y genau die gleiche Zeichenfolge sind (gleiche Länge und gleiche Zeichen an den entsprechenden Stellen); andernfalls wird zurückgegeben falso .
  12. Wenn Typ(x) boolesch ist, wird wahr wenn x und y beide wahr oder beides falso ; andernfalls, Rückkehr falso .
  13. Rückgabe wahr wenn sich x und y auf dasselbe Objekt beziehen oder wenn sie sich auf miteinander verbundene Objekte beziehen (siehe 13.1.2). Andernfalls wird zurückgegeben falso .

Interessant ist Schritt 11. Ja, Zeichenketten werden als Werttypen behandelt. Aber das erklärt nicht, warum new String("a") !== "a" . Haben wir einen Browser, der nicht ECMA-262-konform ist?

Nicht so schnell!

Lassen Sie uns die Typen der Operanden überprüfen. Probieren Sie es selbst aus, indem Sie sie in typeof() . Ich finde, dass new String("a") ein Objekt ist und Schritt 1 angewendet wird: return falso wenn die Typen unterschiedlich sind.

Wenn Sie sich fragen, warum new String("a") keine Zeichenkette zurückgibt, wie wäre es mit einer Übung zum Lesen einer Spezifikation? Viel Spaß dabei!


Aidiakapi schrieb dies in einem Kommentar unten:

Aus der Spezifikation

11.2.2 Der neue Operator :

Wenn Type(constructor) nicht Object ist, wird eine TypeError-Ausnahme ausgelöst.

Mit anderen Worten, wenn String nicht vom Typ Object wäre, könnte er nicht mit dem new-Operator verwendet werden.

neu gibt immer ein Objekt zurück, auch bei Zeichenfolge auch Konstrukteure. Und ach! Die Wertesemantik für Zeichenketten (siehe Schritt 11) ist verloren.

Und das bedeutet letztendlich: new String("a") !== "a" .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X