JavaScript不同类型相等比较总结

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

特殊情况

  1. 返回其他数字
Number.prototype.valueOf = function() {
    return 3;
}

new Number(2) == 3  // true
  1. 假值的相等比较
"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
  1. 极端情况
[] == ![]          // 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