1

So I am a beginner at javascript and learnt that there are only a limited falsy values: false, 0, -0, BigInt 0n, "", null, undefined, NaN
Yet when I use the == operator with truthy values, this doesnt seem to be the case.
I am unable to understand the issue with the equality operator and the boolean outputs.

// outputs are written as comments
console.log(false == "0"); //true
console.log(false == []); //true
console.log(Boolean("0")); //true
console.log(Boolean([])); //true
console.log(Boolean([]) == []); //false
asked Jan 26, 2025 at 19:45
3
  • 3
    Because == performs a multi-step type conversion to convert both sides to the same type. This logic is counterintuitive in many cases - just use === instead Commented Jan 26, 2025 at 19:51
  • 1
    But if you're familiar with PHP: think of it as PHP. == is "can I convert one of these into the other, somehow, whereas === is "are these two things actually the same". You want the latter so much that there's no point in ever using == unless you absolutely know why you need type coercive equality. Commented Jan 26, 2025 at 20:20
  • 1
    Yes always use === strict equality or !== strict inequality. As a JS coder you can go through life never needing to use == or != Commented Jan 26, 2025 at 20:21

2 Answers 2

4

The equality operator performs a series of type coercions in case the types mismatch, this is sometimes counterintuitive. As a rule of thumb, values of different types are usually converted to a number before comparing them again as numbers:

false == "0"
0 == "0"
0 == 0
true

As specified:

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

If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).

——-

The rules of == have little to do with truthiness - to observe whether a value would be truthy or falsy, use !!(<expression>) or Boolean(...) which forces a ToBoolean(...) conversion.

answered Jan 26, 2025 at 20:03
Sign up to request clarification or add additional context in comments.

2 Comments

Is "ToNumber" equivalent to Number(x) or does it have its own separate rules?
@mpen yes
3

I believe you're running into this: https://stackoverflow.com/a/14581884/65387

The false is also converted to 0 so you have 0 == 0 which is of course true.

For false == [], you're hitting the object case (typeof [] === 'object'), so it's doing Primitive coercion, specifically this paragraph:

Neither {} nor [] have a Symbol.toPrimitive method. Both {} and [] inherit valueOf() from Object.prototype.valueOf, which returns the object itself. Since the return value is an object, it is ignored. Therefore, toString() is called instead. {}.toString() returns "[object Object]", while [].toString() returns "", so the result is their concatenation: "[object Object]".

So [] is converted to "", so then you have false == "".

And then I believe you're hitting this:

If one of the operands is a Boolean but the other is not, convert the boolean to a number: true is converted to 1, and false is converted to 0. Then compare the two operands loosely again.

Then "" is also converted to 0.

answered Jan 26, 2025 at 19:57

1 Comment

Thanks. Was getting tired of searching around for the specific paragraph.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.