今天是奇舞前端特训营 JavaScript 课程的第一天。下午的时候给学生介绍 JavaScript 的基本类型,例子中有个有趣的问题,因为时间仓促,没能详细解释。所以写一篇文章来解释,正好也考考大家:
问题:为什么 [ ] == false,而 !![ ] == true?
这是一个很有迷惑性的问题。咋一看,不可能啊?如果 [ ] == false,那么 !![ ] 相当于 !!false,难道不是为 false 吗,为什么会是 true 呢?会不会是引擎 bug,搞错了?
console.log([] == false, !![] == true); // true, true
事实上不是 bug,这与 ECMA 规范和类型转换有关。我们知道,非严格比较操作符 == 是会做强制类型转换的,那么根据 ECMA 262 它的规则是:
来源:http://www.ecma-international.org
注意一下:
所以 [] == false
的比较是对 x 执行 ToPrimitive(x),然后和 ToNumber(false) (为 0)进行比较。
看一下 ToPrimitive:
来源:http://www.ecma-international.org
来源:http://www.ecma-international.org
来源:http://www.ecma-international.org
根据上面的规则对于 ToPrimitive([ ]),先执行 [].valueOf()
,返回 result 的是 [ ],因为 Type(result) 是 Object,所以继续执行 [].toString()
,返回 ""
。
因此实际上最终是比较 "" == 0
,结果为 true。
再来看 !![] == true
:
按照优先级,先执行 !![]
,根据规范,实际上是 !!(ToBoolean([]))
:
而 ToBoolean 的规则是:
所以 ToBoolean([])
被转成 true,!!true
自然是 true 了。
所以这就是 [] == false
而 !![] == true
的真正原因了。这也是为什么我们不能用 if(!array)
来判断空数组而要用 if(array.length === 0)
来判断空数组的原因。
同样,还有 [0] == false
而 !![0] == true
,现在你自己能分析出原因了。
以上就是今天的内容,如果有任何疑问,欢迎留言讨论~
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8