相等运算符的转换
此文由好友李涛整理: https://ltaoo.github.io/
在使用jshint对代码进行质量检测时,会对if(vari == 0){...}
报错,修改建议是使用===
而不要使用==
,第一反应是配置文件中强制要求使用===
,毕竟===
可靠性更高,但if(var i == 1){...}
却不会报错,这就表示配置中并没有强制要求使用===
,而是使用==
和 0 进行比较可能会出现不可预知的问题。同样的情况还有if(var i == ''){...}
。
究竟是什么不可预知的问题?
if(var i == '')
可能是用来判断是否填写了表单,但是0 == ''
为true
,这就不符合预期了。
=
、==
和===
这三个我们知道有不同的含义,分别为赋值、相等、恒等。
使用==
时存在对比较的数据类型转换,之前一直认为是将两边都转换为布尔类型再进行比较,实际并不是。
举个栗子:
|
|
如果按照“转换为布尔类型再进行比较”,则应该返回true
因为’1’和2都是true,但实际上述代码返回false
,因为’1’转换为1,而1并不等于2。
所以记录下具体的转换规则方便查阅。
转换规则
类型相同时
如果类型相同,就按照恒等的规则。
类型不同时
毫无疑问这种情况太多了。
1、null 和 undefined
相等
2、数字 和 字符串
先将字符串转换为数字,然后使用转换后的值进行比较。
3、true/false 和 其他类型
如果其中一个值是true,则将其转换为1再进行比较。如果其中一个值是false,则将其转换为0再进行比较。
4、对象 和 数字或字符串
对象调用自身的toString()
或valueOf()
方法来转换为原始值,然后再进行比较。
5、其他
均不相等。
从这一条可以判断出对象与对象、数组与数组均不相等。无论什么情况:
|
|
还有就是null
和undefined
存在的情况需要注意。
- null 和 除了 null、undefined 外的都不相等。
- undefined 同理。
规律
- 1、如果存在布尔值,优先将布尔值转换为数字,然后就是数字与其他类型,会将其他类型进行转换,最后就是数字与数字进行比较。
- 2、剩下就是字符串与对象,会将对象调用
toString
或者valueOf
转换为原始值,这时就是字符串与字符串的比较了。
总结
其实最终是比较数字而不是比较布尔类型。对象转换为原始值后一般是字符串或者数值。
参考
- 《JavaScript权威指南》-p76