一、 相等操作符(==)
==
是面试的一个难点,其算法复杂多样,泛化程度低,就连资深的Javscript程序员也会感到困惑,在eslint的默认设置下也禁止了使用==
操作符。
下面的表格是不同类型的值使用相等操作符比较后的结果。
类型(x) | 类型(y) | 结果 |
---|---|---|
null | undefined | true |
undefined | null | true |
数字 | 字符串 | x == toNumber(y) |
布尔值 | 任何类型 | toNumber(x) == y |
字符串或数字 | 对象 | x == toPrimitive(y) |
如上图,x
与y
就是==
号的左边右边,当等号两侧类型不同且都为原始类型的时候,字符串类型与布尔类型会做一个toNumber
的转换,这也是为什么有人说相等运算符偏爱数字,如果另外一边时对象类型,则优先将对象类型使用toPrimitive(转为原始类型)
其中toNumber
与toPrimitive
这个方法是内部的,比较的时候会自动执行.
注意:没有列在这个表格的情况都返回false,如
{} == {} // false
{} == !{} // false
1. ToNumber方法对不同类型的返回结果
值类型 | 结果 |
---|---|
undefined | NaN |
null | +0(+0等于-0) |
布尔值 | true为1,false为0 |
数字 | 数字对应的值 |
字符串 | 将字符串解析成数字,如果字符串中包含字母,返回NaN,如果是数字字符组成,转换为数字,空字符为0 |
对象 | Number(toPrimitive(value)) |
2. ToPrimitive方法对不同类型返回的结果
值类型 | 结果 |
---|---|
对象 | 如果对象的valueOf方法是原始值(String、Boolean、Number),返回其原始值。如果valueOf不是原始值,则使用对象的toString方法返回原始值,其他情况都返回一个错误 |
以下是valueOf方法对常见对象类型返回的结果
值类型 | 结果 |
---|---|
{} | {} |
[] | [] |
注意 : 上述的的valueOf都不会转为原始类型,也就是说原始的对象、数组类调用toPrimitive只能使用toString()
以下是toString方法对常见对象类型返回的结果
值类型 | 结果 |
---|---|
{} | [Object object] |
[] | '' (相当于使用了一次join) |
3. 总结
- NaN与什么都不相等
- xy为null或者undefined 返回true
- 如果x和y 为String、Number、Boolean并且类型不一致,使用toNumber转为数字比较
- x或y有一方是对象,另一方是布尔,则对象先使用toPrimitive()转化比较
4. 实战
'pack' == true // false toNumber(pack)为NaN
[] == ![] // true
// 相当于布尔值与任何类型比较,当布尔值转为数字时,相当于对象与数字比较
// 右边:![] = false
// 左边toPrimitive([])= '' ,toNumber('') = 0
// 0 == false -> 0==0 // true
[] == [] // false 引用地址不同 你可以理解为没有出现在上表
undefined == false // false 这种比较方式你可以理解为没有出现在上表
ps :当初在网上找的野鸡博客狗屁不通,所以解决问题最好是翻文档或者是看权威机构的书籍,不然只会坑了自己!!
网友评论