携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
前言
根据数学的推论,当 a = b 且 b = c 时,则 a == c 。
然而在 JS 中有时却不是如此,[] == 0 时为 true,0 == '0'时也是为 true,但是,[] == '0'却是为 false:
这里面有一个就做 隐式转换 的家伙在搞鬼,不能使用常规的数学推论。
原理
在 JS 中使用 == 时比较两个数据时,若是两个数据的类型不相同,它会尝试强制类型转换为相同的原始值,然后在进行比较,这就是常说的 隐式转换。(详细)
也就是说,其实从一开始 [] == 0 时,就已经经过了隐式转换,并不是真的 [] == 0,具体步骤如下:
- 因为有数组的存在,所以要先将数组转换为原始值;
[]调用toString函数转换为空字符串'';- 所以
[] == 0变成了'' == 0,当字符串与数字进行比较时,会将字符串转换为数字,空字符串转换为数字就是0;- 所以
'' == 0变成了0 == 0,所以返回true。
0 == '0' 也是如此:
- 当字符串与数字进行比较时,会将字符串转换为数字,所以字符串
'0'会变成数字0;- 于是,
0 == '0'变成了0 == 0,所以返回了true;
当 [] == '0' 时,会经历如下步骤:
- 因为有数组的存在,所以要先将数组转换为原始值;
[]调用toString函数转换为空字符串'';- 所以
[] == '0'变成了'' == '0',这两个字符串自然就是不相等的,所以返回false;
发散
因为有隐式转换的存在,是否可以用于判断数组是否为空?
常规判断数组是否为空时,都是通过长度进行判断,即 array.length === 0,如果可以写成 array == 0 岂不是更加简便。
答案是可以,但不完全可以。虽然通过上面的推导,可以得出 [] == 0 的结论,但是并不是只有空数组会等于 0,还有以下这些:
因为经过 隐式转换 的处理,使得这些情况也能等于 0,所以最好不用隐式转换来判断数组是否为空。