JavaScript不同类型相等比较总结
字符串和数字之间的相等比较
ES5规范 11.9.3.4-5 规定
(1)如果 Type(x) 是数字,Type(y) 是字符串,返回 x === ToNumber(y)
(2)如果 Type(x) 是字符串,Type(y) 是数字,返回 ToNumber(x) === y
42 == "42" // true
42 === "42" // false
其他类型和布尔型之间的相等比较
ES5规范 11.9.3.6-7 规定
(1)如果 Type(x) 是布尔型,返回 ToNumber(x) == y
(2)如果 Type(y) 是布尔型,返回 x == ToNumber(y)
"42" == false // false
"0" == false // true
"0" == true // false
"42" == true // false
null 与 undefined 之间的相等比较
ES5规范 11.9.3.2-3 规定
(1)如果 x 为 null,y 为 undefined,返回 true
(2)如果 x 为 undefined,y 为 null,返回 true
在 == 比较中 null 和 undefined 相等,除此之外其他的类型的值与它们都不相等
null == undefined // true
null == null // true
undefined == undefined // true
null == false // false
null == 0 // false
null == '' // false
undefined == false // false
undefined == 0 // false
undefined == '' // false
对象和非对象之间的相等比较
ES5规范 11.9.3.8-9 规定
(1)如果 Type(x) 是字符串或数字,Type(y) 是对象,返回 x == ToPrimitive(y)
(2)如果 Type(x) 是对象,Type(y) 是字符串或数字,返回 ToPrimitive(x) == y
// ToPrimitive指代获取对象原始值的方法,包括 ToString, valueOf 等
可拆封对象,ToPrimitive返回基本数据类型值:
a = "abc"
b = Object(a)
a === b // false
a == b // true
不可拆封对象,ToPrimitive返回常规对象:
a = null
b = Object(a) // 和Object()一致
a == b // false
a = undefined
b = Object(a) // 和Object()一致
a == b // false
a = NaN
b = Object(a) // 和Object()一致
a == b // false
特殊情况
- 返回其他数字
Number.prototype.valueOf = function() {
return 3;
}
new Number(2) == 3 // true
- 假值的相等比较
"0" == null // false
"0" == undefined // false
"0" == false // true -- "0" == ToNumber(false) -> "0" == 0 -> ToNumber("0") == 0 -> 0 == 0 -> true
"0" == NaN // false
"0" == 0 // true -- ToNumber("0") == 0 -> 0 == 0 -> true
"0" == "" // false
false == null // false
false == undefined // false
false == NaN // false
false == 0 // true -- ToNumber(false) == 0 -> 0 == 0 -> true
false == "" // true -- ToNumber(false) == "" -> 0 == "" -> 0 == ToNumber("") -> 0 == 0 -> true
false == [] // true -- ToNumber(false) == [] -> 0 == [] -> 0 == ToString([]) -> 0 == "" -> true
false == {} // false -- ToNumber(false) == {} -> 0 == {} -> false
"" == null // false
"" == undefined // false
"" == NaN // false
"" == 0 // true -- ToNumber("") == 0 -> 0 == 0 -> true
"" == [] // true -- "" == ToString([]) -> "" == "" -> true
"" == {} // false
0 == null // false
0 == undefined // false
0 == NaN // false
0 == [] // true -- 0 == ToString([]) -> 0 == "" -> true
0 == {} // false -- 0 == ToString({}) -> 0 == "[object Object]" -> false
- 极端情况
[] == ![] // true
/*
[] == !ToBoolean([])
-> [] == false
-> [] == ToNumber(false)
-> [] == 0
-> ToString([]) == 0
-> "" == 0
-> true
*/
2 == [2] // true -- 2 == ToString([2]) -> 2 == "2" -> 2 == ToNumber("2") -> 2 == 2 -> true
"" == [null] // true -- "" == ToString([null]) -> "" == "" -> true
0 == "\n" // true -- 0 == ToNumber("/n") -> 0 == 0 -> true