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
2 Answers 2
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.
2 Comments
Number(x) or does it have its own separate rules?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.
1 Comment
Explore related questions
See similar questions with these tags.
==performs a multi-step type conversion to convert both sides to the same type. This logic is counterintuitive in many cases - just use===instead==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.===strict equality or!==strict inequality. As a JS coder you can go through life never needing to use==or!=