==
在转换不同的数据类型时,相等操作符遵循下列基本规则:
-
如果有一个操作数是布尔值,则在比较相等性之前,将其转换为数值;
-
如果一个操作数是字符串,另一个操作数是数值,在比较之前先将字符串转换为数值;
-
如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf() 方法,用得到的基本类型值按照前面的规则进行比较;
-
如果有一个操作数是 NaN,无论另一个操作数是什么,相等操作符都返回 false;
-
如果两个操作数都是对象,则比较它们是不是同一个对象。如果指向同一个对象,则相等操作符返回 true;
-
在比较相等性之前,不能将 null 和 undefined 转成其他值。
-
null 和 undefined 是相等的。
总结:如果相等操作符两边的操作数,不包含 null 或者 undefined,且两个操作数不全是对象,在执行相等比较之前,会先调用 Number() 将两个操作数强制转为 Number 类型,然后进行比较
NaN == NaN; //false (参考第4条规则)
[] == []; //false
[] == ![]; //true
{} == {}; //false
{} == !{}; //false
在比较 [] == ![] 的时候,先计算 ![] 得到布尔值 false
所以实际上比较的是 [] == false
Number([]) == Number(false); // -> 0 == 0 -> true
在比较 {} == !{} 的时候,也是遵守同样的规则:
{} == !{} -> {} == false -> Number({}) == Number(false) -> NaN == 0
ToNumber
- null: 转为0
- undefined:转为NaN
- 字符串:如果是纯数字形式,则转为对应的数字,空字符转为0, 否则一律按转换失败处理,转为NaN
- 布尔型:true和false被转为1和0
- 数组:数组首先会被转为原始类型,也就是ToPrimitive,然后在根据转换后的原始类型按照上面的规则处理
- 对象:同数组的处理
Number(null) // 0
Number(undefined) // NaN
Number('10') // 10
Number('10a') // NaN
Number('') // 0
Number(true) // 1
Number(false) // 0
Number([]) // 0
Number(['1']) // 1
Number({}) // NaN