The abstract comparison (==
) rules are described in ES5 11.9.3 while the rules for logical operators (&&
) are described in ES5 11.11.
In short, ==
is just more complex than &&
. Where &&
just uses the internal ToBoolean()
to evaluate its operands, ==
has various conditions that may result in the use of ToBoolean()
, ToNumber()
, and/or ToPrimitive()
.
(0 == false) == true
:7. If Type(y) is Boolean, return the result of comparison x == ToNumber(y)
ToNumber(false) === 0
, so0 == 0
, sotrue
.('0' == false) == true
:This also passes through step 7, resulting in
'0' == 0
.Then, starting over at the top, it reaching step 5:
5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
ToNumber('0') === 0
, so again0 == 0
, and againtrue
.!!(true && 0) == false
&&
simply returns the 1st operand if it's falsy (ToBoolean(...) === false
), or the 2nd operand.It's strictly
(true && 0) === 0
.And, when used as an
if
condition, the result (0
) will as well be passed throughToBoolean(...)
andToBoolean(0) === false
.!!(true && '0') == true
Again, this returns the 2nd operand,
'0'
.This time, however,
ToBoolean('0') === true
as'0'
is a non-empty String, making it truthy.
Also, if you want simpler comparison rules, use strict comparison (===
, 11.9.6).