J'avais été gêné à ce sujet depuis longtemps, alors j'ai finalement fait des recherches et vous donner cette raison de longue haleine pour laquelle les choses sont comme elles sont.
De la spécification :
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)
Alors maintenant, nous passons à 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.
C'est tout. L'opérateur triple égal appliqué aux chaînes renvoie vrai si les arguments sont exactement les mêmes chaînes (même longueur et mêmes caractères aux positions correspondantes).
Cela ===
fonctionnera donc dans les cas où nous essayons de comparer des chaînes qui pourraient provenir de différentes sources, mais qui, nous le savons, finiront par avoir les mêmes valeurs - un scénario assez courant pour les chaînes en ligne dans notre code. Par exemple, si nous avons une variable nommée connection_state
et que nous souhaitons savoir dans lequel des états suivants se ['connecting', 'connected', 'disconnecting', 'disconnected']
trouve actuellement, nous pouvons utiliser directement le===
.
Mais il y a plus. Juste au-dessus de 11.9.4, il y a une courte note:
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.
Hmm. Et maintenant? Les cordes obtenues de l'extérieur peuvent, et très probablement, être unicodey étranges, et nos doux ===
ne leur rendront pas justice. En vient localeCompare
à la rescousse:
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.
On peut rentrer maintenant.
tl; dr;
Pour comparer des chaînes en javascript, utilisez localeCompare
; si vous savez que les chaînes n'ont pas de composants non ASCII car ce sont, par exemple, des constantes de programme internes, alors cela ===
fonctionne aussi.
JavaScript case insensitive string comparison
sur stackoverflow.com/questions/2140627/…