Tôi đã bị làm phiền về điều này từ lâu, vì vậy cuối cùng tôi đã nghiên cứu nó và đưa ra lý do dài dòng này cho lý do tại sao mọi thứ lại diễn ra như vậy.
Từ thông số kỹ thuật :
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)
Vì vậy, bây giờ chúng ta đi đến 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.
Đó là nó. Toán tử ba bằng được áp dụng cho các chuỗi trả về đúng iff các đối số chính xác là cùng một chuỗi (cùng độ dài và cùng ký tự ở các vị trí tương ứng).
Vì vậy, ===
sẽ hoạt động trong các trường hợp khi chúng tôi cố gắng so sánh các chuỗi có thể đến từ các nguồn khác nhau, nhưng chúng tôi biết cuối cùng sẽ có cùng các giá trị - một kịch bản đủ phổ biến cho các chuỗi nội tuyến trong mã của chúng tôi. Ví dụ: nếu chúng ta có một biến có tên connection_state
và chúng ta muốn biết một trong những trạng thái sau đây ['connecting', 'connected', 'disconnecting', 'disconnected']
là gì, chúng ta có thể trực tiếp sử dụng ===
.
Nhưng còn nhiều hơn thế. Chỉ trên 11.9.4, có một lưu ý ngắn:
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.
Hừm. Gì bây giờ? Các chuỗi thu được từ bên ngoài có thể, và rất có thể sẽ, là unicodey kỳ lạ, và người hiền lành của chúng ta ===
sẽ không làm cho họ công bằng. Để localeCompare
giải cứu:
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.
Chúng ta có thể về nhà bây giờ.
tl; dr;
Để so sánh các chuỗi trong javascript, sử dụng localeCompare
; nếu bạn biết rằng các chuỗi không có các thành phần không phải ASCII vì chúng là, ví dụ, các hằng chương trình bên trong, thì ===
cũng hoạt động.
JavaScript case insensitive string comparison
trên stackoverflow.com/questions/2140627/ hy