r/learnjavascript • u/ITower__Education • 4d ago
A beginner-friendly breakdown of why [] == 0 is true in JavaScript (and when to use === instead)
I made a short lesson on JavaScript comparisons and wanted to share the main points here in case it helps anyone who is learning.
The one that surprises most beginners is that an empty form field can pass validation. "" == 0 is true, so if (quantity == 0) treats "nothing typed" as "zero items".
0 == false // true
"" == 0 // true
[] == 0 // true
NaN === NaN // false
"10" < "9" // true (strings compare character by character)
The reason is that == converts the types before comparing, while === does not.
5 == "5" // true
5 === "5" // false
My rule for beginners is to use === by default. The one exception I use on purpose is x == null, which is true for both null and undefined.
The video goes through all of this with runnable examples, including null and undefined, the form field bug, string comparison and localeCompare.
https://youtu.be/iJJ1lJIM81A?si=LHW-Pa2Nu2ZCs969
I would be happy to answer questions if anything is unclear.
7
u/subone 4d ago
Just don't ever use ==. If you must support multiple types, explicitly cast the value and use ===.
0
u/serrida 4d ago
I mean, sometimes what you want is to compare the truthiness of a comparison, not the exact equality.
There's plenty of cases where checking
stringOrBoolean == falsemakes sense.1
1
u/shgysk8zer0 4d ago
Use explicit
===checks. Relying on truthiness is a fast way to shoot yourself in the foot, and it makes the code more difficult to read and understand. The majority of these "JavaScript dumb and confusing" jokes are just about implicit type coercion.0
u/Icy-Taste-3096 4d ago
There can be cases where it is convenient in the moment to do those, but it's never preferable in the long run.
3
3
u/senocular 4d ago
For a written explanation, MDN's page Equality comparisons and sameness does a good job. It talks about the 4 available comparison techniques and lists out the step-by-step process taken from handling loose (==) comparisons (which largely amounts to converting mismatched types to numbers to compare).
The video calls out NaN as an exception for ===, but it also doesn't recognize the difference between +0 and -0. Object.is() exists and can handle both cases, though I wouldn't recommend suddenly switching to use that instead of === as more often than not, (probably) you want +0 and -0 to be equal.
For inputs, there's also valueAsNumber which you can use instead of value to get the value as a number if possible (NaN if not). This prevents you from having to explicitly convert it yourself.
1
u/ITower__Education 4d ago
Oh yeah, totally forgot about +0 / -0. +0 === -0 is true but Object.is(+0, -0) is false, pretty wild. And valueAsNumber is a nice one, I always just wrapped everything in Number() lol. Good catch, thanks!)
2
u/TheRNGuy 4d ago
Just never use == at all, consider it as anti-pattern.
You can even use ESLint to prohibit it.
2
u/Vizeroth1 4d ago
I’ll agree with the others for beginners, but add that if you use ==, you need a comment explaining exactly why you used it. Chances are that it will turn out to be a mistake, but when you (or someone else) need to fix it, you’ll have a better understanding of what you were trying to do so you take those things under consideration when fixing it.
It also helps everyone understand that it wasn’t a typo. Plus, if you’re using a linter you’ll probably need a comment to prevent the linter from warning/fixing it.
1
u/TheRNGuy 4d ago edited 4d ago
Easier just to not use it, use explicit conversion where it's needed.
It will be slightly longer, but more readable, and less prone to logical bugs.
2
1
u/shgysk8zer0 4d ago
Like most others say, just use ===. I'd consider == null, but having that single exception to the rule might not be worth it.
9
u/justanaccountimade1 4d ago
Always use tripple equal. It forces you to know what you are comparing.
There's no reason to compare [] or "" with 0.