var arr = [];
Boolean(arr) // true
Boolean(!arr) // false
arr == arr // true
arr == !arr // true ??? what ???
我不想得到“建议使用===
而不是==
的答案”。
我想知道这种现象的原因以及JavaScript类型转换的原理。
答案 0 :(得分:7)
JS中的类型转换,特别是关于松散相等性的转换,是一个棘手的问题。
回答“为什么这种特殊的松散相等性会以这种方式进行评估”的最佳起点总是咨询this table of equality comparisons by operand type。
在这种情况下,我们可以看到对于[] == false
,操作数A是一个对象,操作数B是一个布尔值,因此执行的实际比较将是ToPrimitive(A) == ToNumber(B)
。
右边很简单; ToNumber(false)
的值为0
。完成并完成。
左侧更复杂;您可以检查the official ECMAScript spec以获得ToPrimitive
的完整文档,但是您真正需要知道的是,在这种情况下,它可以归结为A.valueOf().toString()
,在空数组的情况下,它只是空字符串""
因此,我们最终评估了相等性"" == 0
。字符串/数字==
对该字符串执行ToNumber
,而ToNumber("")
为0
,因此我们得到0==0
,它当然是{{1} }。
答案 1 :(得分:-1)
Double equals ==
在尝试检查相等性之前对值执行一定数量的类型强制。
因此arr == arr
会返回您所期望的true,因为您实际检查的是[] == []
和等式的两边是否是同一类型。
arr == !arr
实际上正在检查是否[] == false
。然后==
对[]
值执行类型强制。正如Hamms所指出的那样,这不会执行 boolean 转换,而是将[]
转换为原语,由于某种原因,该原语为空字符串。所以现在我们的方程是'' == false
。此操作两侧的类型仍然不同。因此,类型强制将再次出现,并且由于javascript中的true和falsey值,''
的计算结果也为false。现在,等式变为false == false
,这显然是正确的。