前置知识
假值
为什么提到假值,而不是真值是因为真值真的是太!多!了!但是假值只有以下这么几个:
undefined
null
false
+0、-0、NaN
""
除此以外别的值做强制类型转换的时候都是真值 PS:有兴趣的同学可以试试 new Number(0)之类的通过对象包装的假值的结果,不过这并不常用故不属于本次讨论范畴。
!![]; //false
!1; //false
!0; //true
以此类推来进行显式的强制转换
undefined == null参考规范 11.9.3 节抽象相等比较算法可得出 undefined == null 为 true 的结论。 PS:本次计算规则为抽象相等比较算法的总结,细节可参考上文 11.9.3 节规范。/true
ToPrimitive简单来说你只需要知道如果某个对象([], )之类的要进行隐式类型转换,那么里面会顺序执行两个操作。即 x.valueOf().toString()。这里有一个不常用的点要注意。我说的是对象类型进行“隐式”类型转化,如果是显式则不是如此。看下例子:
var a = {
valueOf: () => 1,
toString: () => 233,
};
a + ""; // 1
String(a); // 233
隐式转化是按照先 valueOf 后 toString 的顺序执行,如果显式调用会直接执行 oString,不过显式调用在 js 中覆盖率没有隐式的多,知道即可。
JavaScript 计算 x == y 规则
x,y 如果类型相同
这个部分相信有问题的同学百度一下就好。数字的比大小,字符串比大小。里面需要小心的就是 NaN != NaN 以及 对象 如何比较大小?([1] != [1])
重点:x,y 类型不同
1. x,y 一方为布尔值如果 x,y 其中一个是布尔值,那么对这个布尔值进行 toNumber 操作。发现问题了么童鞋们,来看下面代码:
42 == true; // false
不了解规范的会认为,42 是真值啊!42 会转换为 true!你别说如 if(42)这个 42 确实是真值。但是我们现在在讨论“==”下的转换,那么请记住规范规定了:类型不同时若一方是布尔值,是对布尔值进行类型转化即 true => 1,之后我们就可以理解为什么 42 不等于 true 了因为 1!= 42
2. x,y 为数字和字符串将字符串的一方进行 toNumber()操作
2. x,y 一方为对象将对象进行 ToPrimitive()操作
计算示例代码结果
2 == truetrue => 一方为布尔值:true => 1
2 != 1
true => 一方为布尔值:false => 0
2 != 0
1、[]为对象: ToPrimitive([]) => [].valueOf().toString() => ""
2、false为布尔:false => 0
3、等式变为:"" == 0
4、一方为数字,一方为字符
Number("") => 0
=> 0 == 0
1、false为布尔:false => 0
2、等式变为:"0" == 0
3、一方为数字,一方为字符
Number("0") => 0
=> 0 == 0
1、左侧[]为对象: ToPrimitive([]) => [].valueOf().toString() => ""
2、右侧![]先进行显式类型转换:false(除了上文提到的假值剩下都是真值)
3、等式变为: "" == false
4、一方为布尔:false => 0
5、等式变为:"" == 0
5、一方为数字,一方为字符
Number("") => 0
=> 0 == 0