0 vs '0' with boolean operators
Asked Answered
C

2

6

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

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

Why?

Confrere answered 27/6, 2013 at 2:7 Comment(3)
The operands of an equality comparison follow certain rules. With your first two examples, they are converted to numbers, and therefore equal. Using && and ||, the operands are tested for truthyness. The only falsey values are false, 0, "", null, undefined, and NaN. Hopefully this can help: es5.github.io/#x11.9.3Perren
idk about you but when I type (true && 0) into the console I get 0 and when I do (true && '0') I get "0"Budgerigar
@Budgerigar I think they were more or less being used in an if statementPerren
B
6

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

Bolt answered 27/6, 2013 at 2:21 Comment(1)
(true && '0') == true is false actually (as '0' != true). If you want to emphasize the truthiness and the ToBoolean operation you'd better use !!(true && '0')Yoga
T
-2

'0' (or any non-empty string) is 'truthy' in JS. The == operator, however, does some strange type-coercion which is why many prominent JS figures including Crockford highly discourage it. This is a good example of why you should avoid it, it takes the string '0' and coerces it into a falsey value.

Here's a link that explains this process:

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

So even stranger than your example is this:

('1' == true) // true
('2' == true) // false!
Tachygraphy answered 27/6, 2013 at 2:31 Comment(1)
Au contraire mon ami, it absolutely is related to == and its coercive effect. I never mentioned === so not sure where your comment is coming from.Tachygraphy

© 2022 - 2024 — McMap. All rights reserved.