本文转载自: https://www.h5jun.com/post/why-false-why-true.html
问题:为什么 [ ] == false,而 !![ ] == true?
这是一个很有迷惑性的问题。咋一看,不可能啊?如果 [ ] == false,那么 !![ ] 相当于 !!false,难道不是为 false 吗,为什么会是 true 呢?会不会是引擎 bug,搞错了?
console.log([] == false, !![] == true); // true, true
事实上不是 bug,这与 ECMA 规范和类型转换有关。我们知道,非严格比较操作符 == 是会做强制类型转换的,那么根据 ECMA 262 它的规则是:
来源:http://www.ecma-international.org
![](https://img.haomeiwen.com/i7707397/f28a4fa2411ffcd5.png)
注意一下:
第 7 条:If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
第 9 条:If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.
所以 [] == false 的比较是 ToNumber(false) (为 0),然后和对 x 执行 ToPrimitive(x) 进行比较。
看一下 ToPrimitive:
来源:http://www.ecma-international.org
![](https://img.haomeiwen.com/i7707397/76d5fefb3ce61da2.png)
来源:http://www.ecma-international.org
![](https://img.haomeiwen.com/i7707397/0ebe530523979eb8.png)
来源:http://www.ecma-international.org
![](https://img.haomeiwen.com/i7707397/6d5ac3fcd546c688.png)
根据上面的规则对于 ToPrimitive([ ]),先执行 [].valueOf(),返回 result 的是 [ ],因为 Type(result) 是 Object,所以继续执行 [].toString(),返回 ""。
因此实际上最终是比较 "" == 0,结果为 true。
再来看 !![] == true:
按照优先级,先执行 !![],根据规范,实际上是 !!(ToBoolean([])):
![](https://img.haomeiwen.com/i7707397/aa861680a689b26d.png)
而 ToBoolean 的规则是:
![](https://img.haomeiwen.com/i7707397/e7b753f7f63c74a6.png)
所以 ToBoolean([]) 被转成 true,!!true 自然是 true 了。
所以这就是 [] == false 而 !![] == true 的真正原因了。这也是为什么我们不能用 if(!array) 来判断空数组而要用 if(array.length === 0)来判断空数组的原因。
同样,还有 [0] == false 而 !![0] == true,现在你自己能分析出原因了。
思考: []==![] //true
首先 ![] 将 [] 转成 boolean, 此时题目为 [] == false ?
参考标准第 7 条, 题目变为 [] == 0 ?
参考第 9 条,题目变为 ToPrimitive([ ]) == 0 ?根据上面的规则对于 ToPrimitive([ ]),先执行 [].valueOf(),返回 result 的是 [ ],因为 Type(result) 是 Object,所以继续执行 [].toString(),返回 ""。 “” = 0?
返回 true
ToPrimitive 函数,它是对象类型到基本类型转换的实现者(即,拆箱转换) https://juejin.im/post/5c5011805188252552518470
网友评论