Welcher Gleichheitsoperator (== vs. ===) sollte in JavaScript-Vergleichen verwendet werden?
Lesezeit: 7 Minuten
bcasp
Ich benutze JSLint JavaScript zu durchlaufen, und es gibt viele Vorschläge zum Ersetzen zurück == (zwei Gleichheitszeichen) mit === (drei Gleichheitszeichen) beim Vergleichen idSele_UNVEHtype.value.length == 0 innerhalb eines if Aussage.
Gibt es einen Leistungsvorteil durch den Austausch? == mit ===?
Jede Leistungsverbesserung wäre willkommen, da es viele Vergleichsoperatoren gibt.
Wenn keine Typkonvertierung stattfindet, käme da ein Performance-Gewinn zustande ==?
Verwendung der == Operator (Gleichberechtigung)
true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2; //true, because "2" is converted to 2 and then compared
Verwendung der === Operator (Identität)
true === 1; //false
"2" === 2; //false
Dies liegt daran, dass die Gleichheitsoperator == gibt Zwang anwas bedeutet, dass der Interpreter vor dem Vergleich implizit versucht, die Werte zu konvertieren.
Andererseits ist die Identitätsoperator === macht keinen Zwangrechnet also die Werte beim Vergleich nicht um und ist damit schneller (wie gem Dieser JS-Benchmark test), da ein Schritt übersprungen wird.
Mindestens == Vergleiche sind kommutativ (dh (a==b) === (b==a)) XD
– imkzh
30. November 2021 um 8:38 Uhr
Philippe Leybaert
In den Antworten hier habe ich nichts darüber gelesen, was gleich bedeutet. Manche werden das sagen === bedeutet gleich und vom gleichen Typ, aber das stimmt nicht wirklich. Das bedeutet es tatsächlich beide Operanden verweisen auf dasselbe Objektoder ggf Werttypen, denselben Wert haben.
Nehmen wir also 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
Dasselbe 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 auch:
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. Die Geschichte hat mehr zu bieten, als gleich und vom gleichen Typ zu sein.
Die Regel lautet:
Für Werttypen (Zahlen): a === b gibt true zurück, wenn a und b haben den gleichen Wert und sind vom gleichen Typ
Für Referenztypen: a === b gibt true zurück, wenn a und b verweisen auf genau das gleiche Objekt
Für Saiten: a === b gibt true zurück, wenn a und b sind beides Zeichenketten und enthalten genau die gleichen Zeichen
Saiten: der Sonderfall…
Zeichenfolgen sind keine Werttypen, aber in Javascript verhalten sie sich wie Werttypen, sodass sie “gleich” sind, wenn die Zeichen in der Zeichenfolge gleich und gleich lang sind (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, Zeichenfolgen verhalten sich wie Werttypen? Nun, es hängt davon ab, wen Sie fragen … In diesem Fall sind a und b nicht vom gleichen Typ. a ist vom Typ Objectwährend b ist vom Typ string. Denken Sie daran, dass das Erstellen eines String-Objekts mit der String Der Konstruktor erstellt etwas vom Typ Object das verhält sich wie ein String meistens.
Ich habe heute mit TypeScript begonnen, das von asm/C/C++ kommt, und das war eine SEHR hilfreiche Antwort. Danke Philippe!
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 zu handhaben ist. Aber es ist hilfreich zu verstehen, warum neuer String(“a”) !== “a”.
Bitte lassen Sie mich erklären, wie die Spezifikation zu lesen ist, um diese Frage zu klären. Ich sehe, dass in diesem sehr alten Thema niemand eine Antwort auf den sehr seltsamen Effekt hatte. Wenn Sie also eine Spezifikation lesen können, hilft Ihnen das in Ihrem Beruf enorm. Es 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 strikte Gleichheitsoperator ( === )und nachdem ich durch die Spezifikation gewatet bin, finde ich:
11.9.6 Der strikte Gleichheitsvergleichsalgorithmus
Der Vergleich x === y, wobei x und y Werte sind, ergibt wahr oder falsch. Ein solcher Vergleich wird wie folgt durchgeführt:
1. Wenn sich Typ(x) von Typ(y) unterscheidet, zurückgeben falsch.
2. Wenn Typ(x) undefiniert ist, zurückgeben wahr.
3. Wenn Type(x) Null ist, zurückgeben wahr.
4. Wenn Type(x) nicht Number ist, gehen Sie zu Schritt 11.
5. Wenn x ist NaNRückkehr falsch.
6. Wenn y ist NaNRückkehr falsch.
7. Wenn x derselbe Zahlenwert wie y ist, kehre zurück wahr.
8. Wenn x +0 ist und y –0 ist, kehre zurück wahr.
9. Wenn x –0 ist und y +0 ist, kehre zurück wahr.
10. Rückkehr falsch.
11. Wenn Type(x) String ist, dann zurück wahr wenn x und y genau die gleiche Folge von Zeichen sind (gleiche Länge und gleiche Zeichen an entsprechenden Stellen); ansonsten zurück falsch.
12. Wenn Type(x) Boolean ist, zurück wahr wenn x und y beides sind wahr oder beides falsch; ansonsten zurück falsch.
13. Rückkehr wahr wenn x und y sich auf dasselbe Objekt beziehen oder wenn sie sich auf miteinander verbundene Objekte beziehen (siehe 13.1.2). Ansonsten zurück falsch.
Interessant ist Schritt 11. Ja, Strings werden als Werttypen behandelt. Aber das erklärt nicht warum neuer String(“a”) !== “a”. Haben wir einen Browser, der nicht ECMA-262 entspricht?
Nicht so schnell!
Lassen Sie uns die Typen der Operanden überprüfen. Probieren Sie es selbst aus, indem Sie sie einpacken Art der(). Ich finde, dass neue Zeichenfolge (“a”) ein Objekt ist und Schritt 1 verwendet wird: return falsch wenn die Typen unterschiedlich sind.
Wenn Sie sich fragen, warum neue Zeichenfolge (“a”) gibt keinen String zurück, wie wäre es mit einer Übung zum Lesen einer Spezifikation? Habe Spaß!
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 für Schnur auch Konstrukteure. Und leider! Die Wertesemantik für Zeichenfolgen (siehe Schritt 11) geht verloren.
Und das heißt schließlich: neuer String(“a”) !== “a”.
Ich habe heute mit TypeScript begonnen, das von asm/C/C++ kommt, und das war eine SEHR hilfreiche Antwort. Danke Philippe!
– Sander Bouwhuis
3. Februar um 17:08 Uhr
kabirbaidhya
Ich habe dies in Firefox mit getestet Feuerwanze Code wie diesen verwenden:
console.time("testEquality");
var n = 0;
while (true) {
n++;
if (n == 100000)
break;
}
console.timeEnd("testEquality");
und
console.time("testTypeEquality");
var n = 0;
while (true) {
n++;
if (n === 100000)
break;
}
console.timeEnd("testTypeEquality");
Meine Ergebnisse (jeweils fünfmal getestet und gemittelt):
==: 115.2
===: 114.4
Ich würde also sagen, dass der winzige Unterschied (das sind über 100000 Iterationen, denken Sie daran) vernachlässigbar ist. Leistung ist nicht ein Grund zu tun ===. Geben Sie Sicherheit ein (na ja, so sicher, wie Sie es in JavaScript bekommen werden), und die Codequalität ist.
Nun, wie vergleichen sich diese, wenn es eine tatsächliche Typzwangsänderung gibt? == Operator? Denken Sie daran, dann gibt es einen Leistungsschub.
– Hubert OG
13. Juli 2013 um 21:13 Uhr
GROSSER Unterschied bei ordnungsgemäßem Test aus den oben genannten Gründen, um nur die Typungleichheit schneller zu überprüfen. jsfiddle.net/4jhuxkb2
– Doug Morrow
6. Juli 2015 um 17:04 Uhr
Ich denke, die Zeitdifferenz, die wir sehen, liegt daran, dass n eine Zahl ist und 100000 ebenfalls. Sie sollten sie an einer Zeichenfolge “1” überprüfen. Ich nehme an, dass eine Analyse durchgeführt wird und die Zeitdifferenz ansteigt
– Avishay
19. Februar um 18:05 Uhr
9866200cookie-checkWelcher Gleichheitsoperator (== vs. ===) sollte in JavaScript-Vergleichen verwendet werden?yes