The rules for abstract comparison ( == ) are described in ES5 11.9.3 , while the rules for logical operators ( && ) are described in ES5 11.11 .
In short, == simply more complicated than && . Where && simply uses the internal ToBoolean() to evaluate its operands, == has various conditions that may lead to the use of ToBoolean() , ToNumber() and / or ToPrimitive() .
(0 == false) == true :
7. If Type (y) is boolean, return the result of the comparison x == ToNumber (y)
ToNumber(false) === 0 , therefore 0 == 0 , therefore true .
('0' == false) == true :
This also goes through step 7, resulting in '0' == 0 .
Then, starting from above, it reaches step 5:
5. If Type (x) is String and Type (y) is Number, returns the result of the comparison ToNumber (x) == y.
ToNumber('0') === 0 , so again 0 == 0 and again true .
!!(true && 0) == false
&& simply returns the 1st operand if it is false ( ToBoolean(...) === false ) or the second operand.
This is strictly (true && 0) === 0 .
And when used as an if condition, the result ( 0 ) will also be passed through ToBoolean(...) and ToBoolean(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 true.
Also, if you need simpler comparison rules, use strict comparison ( === , 11.9.6 ).
source share