0 == false
和'0' == false
都是'true'
但是,(true && 0)
为'false',而(true && '0')
为'true'。
为什么?
答案 0 :(得分:6)
ES5 11.9.3中描述了抽象比较(==
)规则,而ES5 11.11中描述了逻辑运算符(&&
)的规则
简而言之,==
比&&
更复杂。如果&&
仅使用内部ToBoolean()
来评估其操作数,==
具有可能导致使用ToBoolean()
,ToNumber()
和/或{/ 1}}的各种条件ToPrimitive()
。
(0 == false) == true
:
7。如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)
ToNumber(false) === 0
,所以0 == 0
,所以true
。
('0' == false) == true
:
这也通过了第7步,产生了'0' == 0
。
然后,从顶部开始,它到达第5步:
5。如果Type(x)是String而Type(y)是Number, 返回比较结果ToNumber(x)== y。
ToNumber('0') === 0
,再次0 == 0
,再次true
。
!!(true && 0) == false
&&
只返回第一个操作数,如果它是 falsy (ToBoolean(...) === false
)或第二个操作数。
严格来说是(true && 0) === 0
。
而且,当用作if
条件时,结果(0
)也会passed through ToBoolean(...)
和ToBoolean(0) === false
。
!!(true && '0') == true
再次,这将返回第二个操作数'0'
。
但是,这一次,ToBoolean('0') === true
为'0'
是一个非空字符串,使其成为 truthy 。
此外,如果您想要更简单的比较规则,请使用严格比较(===
,11.9.6)。
答案 1 :(得分:-2)
'0'(或任何非空字符串)在JS中是'truthy'。然而,==运算符做了一些奇怪的类型强制,这就是为什么包括Crockford在内的许多杰出的JS人物高度劝阻它。这是为什么你应该避免它的一个很好的例子,它接受字符串'0'并将其强制转换为假值。
以下是解释此过程的链接:
http://webreflection.blogspot.com/2010/10/javascript-coercion-demystified.html
If Type(x) is Boolean, return the result of the comparison
ToNumber(x) == y: false == 0 and true == 1 but true != 2
所以比你的例子更奇怪的是:
('1' == true) // true
('2' == true) // false!