Ero stato infastidito a lungo per questo, quindi alla fine ho cercato questo e ti ho dato questa ragione lunga e tortuosa del perché le cose sono come sono.
Dalle specifiche :
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)
Quindi ora andiamo a 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.
Questo è tutto. L'operatore triple egals applicato alle stringhe restituisce true se gli argomenti sono esattamente le stesse stringhe (stessa lunghezza e stessi caratteri nelle posizioni corrispondenti).
Quindi ===
funzionerà nei casi in cui stiamo provando a confrontare stringhe che potrebbero essere arrivate da fonti diverse, ma che sappiamo che alla fine avranno gli stessi valori - uno scenario abbastanza comune per le stringhe incorporate nel nostro codice. Ad esempio, se abbiamo una variabile denominata connection_state
e desideriamo sapere in quale momento si trova uno dei seguenti stati ['connecting', 'connected', 'disconnecting', 'disconnected']
, possiamo usare direttamente il===
.
Ma c'è di più. Poco sopra l'11.9.4, c'è una breve nota:
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. E adesso? Le stringhe ottenute esternamente possono, e molto probabilmente lo saranno, un unicodey strano, e il nostro gentile ===
non gli farà giustizia. In viene localeCompare
in soccorso:
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.
Ora possiamo andare a casa.
tl; dr;
Per confrontare le stringhe in javascript, utilizzare localeCompare
; se sai che le stringhe non hanno componenti non ASCII perché sono, ad esempio, costanti di programma interne, allora ===
funziona anche.
JavaScript case insensitive string comparison
su stackoverflow.com/questions/2140627/…