==非严格相等

规范:Section 11.9.3, The Abstract Equality Algorithm

规则

由规范概括出的比较规则:

  1. 如果其中一个操作数为Number类型,另一个操作数为String类型,则先将字符串转为Number类型再比较

  2. 如果其中一个操作数为Boolean类型,则在比较相等性之前,将其转换为Number类型

  3. 如果其中一个操作数为Object类型,另一个操作数为StringNumber类型,则将Object类型的操作数转为基本类型(ToPrimitive

  4. NaN与任何类型的操作数比较都返回false(包括自身)

  5. 如果两个操作数都是为Object类型,则比较它们是不是同一个对象。如果指向同一个对象(指向同一个内存地址),则返回true

其他特殊情况:

  • null == undefined返回true

  • +0 == -0返回true

例:[] == ![]

!操作符优先级高于==,先执行!操作:

1
[] == false

满足上述第2条规则,将Boolean类型的操作数转换为Number类型:

1
[] == Number(false)

得到:

1
[] == 0

满足上述第3条规则,将Object类型的操作数转为基本类型:

1
ToPrimitive([]) == 0

toPrimitive()函数是如何执行的
先调用[].valueOf(),结果是[],不是基本类型,所以继续调用[].toString(),结果是"",是基本类型,返回""

得到:

1
"" == 0

满足上述第1条规则,将字符串转为Number类型:

1
Number("") == 0

最后得到:

1
0 == 0 // true

例:{} == !{}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{} == false

=>

ToPrimitive({}) == Number(false)

=>

"[object Object]" == 0

=>

Number("[object Object]") == 0

=>

NaN == 0 // false