Search code examples
javascriptboolean-expressionboolean-operations

0 vs '0' with boolean operators


0 == false and '0' == false are both 'true'

However, (true && 0) is 'false', while (true && '0') is 'true'.

Why?


Solution

  • 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().

    1. (0 == false) == true:

      7. If Type(y) is Boolean, return the result of comparison x == ToNumber(y)

      ToNumber(false) === 0, so 0 == 0, so true.

    2. ('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 again 0 == 0, and again true.

    3. !!(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 through ToBoolean(...) and ToBoolean(0) === false.

    4. !!(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).