Ich habe mich schon lange darüber aufgeregt, also habe ich schließlich recherchiert und gebe Ihnen diese langatmige Begründung, warum die Dinge so sind, wie sie sind.
De la spec :
Section 11.9.4 The Strict Equals Operator ( === )
The production EqualityExpression : EqualityExpression === RelationalExpression
is evaluated as follows:
- Let lref be the result of evaluating EqualityExpression.
- Let lval be GetValue(lref).
- Let rref be the result of evaluating RelationalExpression.
- Let rval be GetValue(rref).
- Return the result of performing the strict equality comparison
rval === lval. (See 11.9.6)
Also gehen wir jetzt zu 11.9.6
11.9.6 The Strict Equality Comparison Algorithm
The comparison x === y, where x and y are values, produces true or false.
Such a comparison is performed as follows:
- If Type(x) is different from Type(y), return false.
- If Type(x) is Undefined, return true.
- If Type(x) is Null, return true.
- If Type(x) is Number, then
...
- If Type(x) is String, then return true if x and y are exactly the
same sequence of characters (same length and same characters in
corresponding positions); otherwise, return false.
Das war's. Der dreifache Gleichheitsoperator, der auf Zeichenketten angewandt wird, gibt true zurück, wenn die Argumente genau die gleichen Zeichenketten sind (gleiche Länge und gleiche Zeichen an den entsprechenden Positionen).
Así que ===
funktioniert in den Fällen, in denen wir versuchen, Zeichenketten zu vergleichen, die aus unterschiedlichen Quellen stammen könnten, von denen wir aber wissen, dass sie letztendlich die gleichen Werte haben werden - ein häufig genug vorkommendes Szenario für Inline-Zeichenketten in unserem Code. Wenn wir zum Beispiel eine Variable namens connection_state
und wir möchten wissen, welcher der folgenden Zustände ['connecting', 'connected', 'disconnecting', 'disconnected']
ist, können wir direkt die Funktion ===
.
Aber es gibt noch mehr. Direkt über 11.9.4 gibt es eine kurze Notiz:
NOTE 4
Comparison of Strings uses a simple equality test on sequences of code
unit values. There is no attempt to use the more complex, semantically oriented
definitions of character or string equality and collating order defined in the
Unicode specification. Therefore Strings values that are canonically equal
according to the Unicode standard could test as unequal. In effect this
algorithm assumes that both Strings are already in normalized form.
Hm. Was nun? Extern beschaffte Saiten können und werden höchstwahrscheinlich seltsam einfarbig sein, und unsere sanften ===
wird ihnen nicht gerecht. Rein kommt localeCompare
zur Rettung:
15.5.4.9 String.prototype.localeCompare (that)
...
The actual return values are implementation-defined to permit implementers
to encode additional information in the value, but the function is required
to define a total ordering on all Strings and to return 0 when comparing
Strings that are considered canonically equivalent by the Unicode standard.
Wir können jetzt nach Hause gehen.
tl;dr;
Um Zeichenketten in Javascript zu vergleichen, verwenden Sie localeCompare
Wenn Sie wissen, dass die Zeichenketten keine Nicht-ASCII-Bestandteile haben, weil es sich z. B. um interne Programmkonstanten handelt, dann ===
funktioniert auch.