我为这个问题困扰了很久,所以我终于研究了这个,并给你这个冗长的理由来解释为什么事情会这样。
来自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)
所以现在我们去 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.
就是这样。 如果参数是完全相同的字符串(相同的长度和对应位置的相同字符),则应用于字符串的三重等号运算符返回 true。
所以=== 将在我们尝试比较可能来自不同来源但我们知道最终将具有相同值的字符串的情况下工作 - 这是我们代码中内联字符串的常见场景。例如,如果我们有一个名为connection_state的变量,并且我们想知道['connecting', 'connected', 'disconnecting', 'disconnected']现在处于以下哪个状态,我们可以直接使用===。
但还有更多。就在 11.9.4 以上,有一个简短的说明:
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.
嗯。现在怎么办?外部获得的字符串可能而且很可能会是奇怪的 unicodey,而我们温柔的 === 不会公正对待它们。 localeCompare 来救援:
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.
我们现在可以回家了。
tl;dr;
要在 javascript 中比较字符串,请使用 localeCompare;如果您知道字符串没有非 ASCII 组件,因为它们是例如内部程序常量,那么 === 也可以工作。