0 == false
并且'0' == false
都是“真实的”
然而,(true && 0)
是'假',(true && '0')
而是'真'。
为什么?
0 == false
并且'0' == false
都是“真实的”
然而,(true && 0)
是'假',(true && '0')
而是'真'。
为什么?
抽象比较( ==
) 规则在ES5 11.9.3中描述,而逻辑运算符 ( &&
) 规则在ES5 11.11中描述。
简而言之,==
只是比&&
. where&&
仅使用 internalToBoolean()
来评估其操作数,==
具有可能导致使用ToBoolean()
,ToNumber()
和/或的各种条件ToPrimitive()
。
(0 == false) == true
:
7. 如果 Type(y) 为 Boolean,则返回比较结果 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
) 也将通过ToBoolean(...)
and传递ToBoolean(0) === false
。
!!(true && '0') == true
同样,这将返回第二个操作数'0'
.
然而,这一次ToBoolean('0') === true
是'0'
一个非空字符串,使其成为真值。
此外,如果您想要更简单的比较规则,请使用严格比较( ===
, 11.9.6 )。
'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!