While this topic may appear basic and familiar but I think we've all been there, using ==
when ===
was the better choice, only to wonder why our code behaves strangely.
So no "ugh you didn't even know this silly, it was so simple" comments please and let's unravel the mysteries of JavaScript's equality operators together.
Loose Equality
The loose equality operator ==
is designed for type coercion (datatype conversion), allowing JavaScript to convert operands to a common type BEFORE comparison.
While this can be convenient, it can also lead to subtle bugs.
Example 1: String and Number
const a = 10;
const b = '10';
console.log(a == b) // Result: true
Even though
a
is a number andb
is a string, we get true. This is because the type of the variablea
is converted to a string before making the comparison.After the comparison, the value is checked in both the variables. If it's same, we will get true otherwise we will get false.
But that's not a problem, at least the values are same?
Haha, just wait for it..
Example 2: NaN Comparison
NaN == NaN; // Result: false
Due to the complexities of
NaN
, using==
to compareNaN
values will ALWAYS return false.For
NaN
checks, useisNaN()
or a strict comparison:===
.
Example 3: String and Boolean
const a = true;
const b = 'true';
console.log(a == b)
If you thought the answer is true, unfortunately that's not correct.
Surprised huh?
If either operand is a Boolean, it will be converted to a number (true becomes 1 and false becomes 0).
Now, you know why the answer was true, not false in the above example.It is because the value of the variable
a
(true) gets converted to a number before the comparison. So after comparison, we're basically comparing1
and'true'
hence we get false because the variables contain different values.
Pretty unexpected behavior, I TOLD YOU.
Hence many experienced developers favor strict equality operator ===
for its strictness, as it reduces ambiguity and encourages explicit type handling.
Strict Equality
The strict equality operator ===
is, well, very strict. It compares both value and type, making it more predictable and less prone to unexpected results.
Example 1: String and Number
"5" === 5; // Result: false
Since the types are different, the comparison returns false
.
Example 2: Boolean and Number
false === 0; // Result: false
In this case, false and 0 have different types, so the comparison is false
.
Conclusion
In JavaScript, clarity and predictability are vital. While loose equality operator can be convenient, it introduces potential pitfalls and surprises. The choice between ==
and ===
depends on your intent and having knowledge of both of the operators is must but there are reasons you should avoid using ==
in your code as we discussed above.
Hope it helps!
For more such content feel free to connect with me.
LinkedIn: https://www.linkedin.com/in/quratulain
GitHub: https://github.com/QuratAin
Top comments (33)
Sorry, but this is poor advice.
==
is there for a reason, as is===
- learn what they do and use whichever is appropriate on a case by case basis.'Advice' that blanket bans parts of a programming language because they introduce 'surprises' is just a recipe for increasingly uninformed, lower skilled developers.
Unexpected code behaviour, or 'surprises' come when you do not fully understand your code, the code you are working on, or the language you are working with.
Extending on @jonrandy 's comment, the
==
operator is useful to avoid converting data and then check equality.You don't always need something to be the same type to check if it has an equivalent value.
E.g.
You don't really care here if the response comes with the id property as number or if it got stringified and now it's a
"1"
or even if you got a float1.0
, nor you will obtain any benefit by doing:As a rule of thumb, use
===
whenever no conversions are expected to take place to avoid confusion.E.g.
But feel free to use
==
whenever the inherent type casting is good.Not using
==
won't solve bugs on it's own, having tests that cover all possible use-cases will, and AI nowadays helps a lot on that so it has even less sense to "ban" the usage of the loose equality IMHO.Yes, I use that for boolean checks & conversion at once ->
isSomething == "true"
.Simplifies code, converts string containing boolean value to an actual boolean, which can happen when e.g. the value was stringified to send as query string parameter.
Yes!
You can even shorten that in most cases and simply check
Even though is not exactly an equivalent. Please note that the boolean conversion is a bit more tricky that what one may thought.
On the example above the runtime will check that
isSomething
is not null, nor undefined, that doesn't contain a zero as value and so on, whereas checking explicitly if something's equal to true or false is weird in JS, look:you can directly write comparisons in the browser's console to test them out.
To solve that you can use the double negation that will cast to boolean, like so:
or, if you prefer it
so you can
or directly
or
Hope you find better names than I did, tho 😂
Best regards
I've been out of JS & TS for a while, I liked the double exclamation marks, is it still a thing?
What I meant to illustrate is that I found the '==' super useful.
Or did I use it for everything that is not true?
I can't remember but leveraging all boolean operators can greatly improve your code readability, for example one-liner return statements instead of multi-line if statements.
Altho when it really matter, you might indeed be safer using the ===.
If you ask me, one just need to define what's valuable to compare at a given point in the program. Is it the value? value + type? any other thing?
Following the example I used above
if the backend changes and suddenly we get either "2" or 2 or "2.00" or [2] or ["2"] or... it is OK?
Sure, we just want to know which view is involved in this right? so why bother?
By using
==
if the backend changes and returns the same information (same value) wrapped in a different type or structure, the App won't break, we avoid a cut in the service and we don't need to fix and rebuild the App.Now consider the following scenario:
now if the backend returns
"2"
instead of2
... Upsies, we need to fix it, rebuild and redeploy our App, users are not able to use it in the meantime, the company is probably loosing monies.Of course one can rewrite it like so:
but it looks cumbersome to me and I don't believe it brings any value to any developers involved nor to the app itself. We're explicitly instructing the program the same that
==
does by default.If we stress it enough maybe the yoda style is more readable, idk at that point 😂
jokes aside, In this use-case,
==
solution is more resilient and easy to read===
one is less resilient and equally easy to read,===
one is equally resilient to the==
one, but harder to read.In other cases this may be completely different and that's why we have different tools 😅😂
While I agree in general, particularly the response example can be a trap. If you're used to using
==
there, you might well end up accidentally using it for== 0
, where it does make an annoying difference.Sure, now regarding the example I was thinking about, most databases are 1-indexed, meaning that the first element of their indexes is 1, including auto-increment initial values.
But again, it's a tool and it has sense in certain situations, the same way you'll probably use
var
when coding a videogame with JavaScript because you want (or even need) certain stuff to be in the global scope.And yet again, having a test to check what happens when the value is
== 0
, if it makes sense in this specific function/method will hint you at possible undesired computation paths or errors before you release the code to production, plus consistent JSDoc will make others (and yourself in the future) aware of what it's supposed to do.Best regards
It's an unnecessary tripping hazard. It's rather my code be expressive then depend on every Dev that reads it to understand the intricacies of
===
Vs==
fair enough 😂
Makes sense.
Why You Should Never Use (==) in JavaScript --> Why You Should Avoid Using (==) in JavaScript.
--> When should you avoid using
==
in JavaScript 😁If you're the only developer of your code, that's fine. But if you work on a long term project with changing teams with a variety of seniority levels, you can't assert that they know your code, or that you know theirs. If I see a
==
in my company's code, I can never know if that was on purpose or a mistake, but if we enforce use of===
, there's no more ambiguity.I prefer clear code than clever code any day.
== null
or!= null
is hardly clever though. It is compact, it is common, it is useful, and pretty much anyone writing JS would be expected to eventually know it. It is a great conversation starter when someone encounters it the first time! You can teach people about the differences of undefined and null. Very valuable to have it in about any codebase.I think this is at least a matter of taste.
In most cases, strict comparison is not required, and it is more common to use null == undefined.
If you know that other comparison operators convert to numbers and then compare them if the types are different, there will be no confusion.
I agree, its important to have knowledge of how both work as i already mentioned in conclusion. But after you've understood something its more important to balance best practices with practical application.
How will a junior dev ever gain a full understanding of how they both work and when it is appropriate to use each, if people insist on an irrational blanket ban on
==
?Best practice is to use the right tool for the job.
The blog points out the 'why nots' not to stop learning, but to guide it. If we don't understand why something's bad, how can we get better anyway. No one's blocking the room for learning here.
Agree!
The result:
Its interesting to see the difference, definitely takes time for JS to do the coercion.
But in the real world it wouldn't really have any significant effect unless you're doing a million comparisons for some reason, in which case you're doing something wrong :D
Of course, my code is a bit artificial. And, of course, a well-formed real-life page contains less than a million comparisons. Even though it can have many comparisons, we sometimes can't imagine how many. Algorithms complexity estimation is always like an art ;) It could be sensitive. Anyway, it depends on functionality.
Yea, good to know that it does make a difference
Thank you for this addition.
While it's ok to use
==
sometimes, you're more likely to introduce bugs by relying on it, and will have a harder time debugging them too. Talking from experience. This is why I always enable the eslint rule eqeqeq in my projects that prevents me from accidentally, or purposely, using==
instead of===
.There once was a dev who'd opine,
That linting was far from divine.
"It nags and it picks,
At my clever code tricks,
And refrains from a neat, clean design."
#abotwrotethis
Funny but I think the meaning is a bit lost in this one.
Hmmm, made sense to me. Though I guess it's pushing less common English to make the rhyme.
I felt like the opposite from "And refrains from a neat, clean design" was what I was hinting at
You should understand both and use both at the right time. For example, if I'm retrieving a value from a database and want to perform an action when the value is “true”, but I don't mind if the "true" value comes as a boolean or as a string, then I should use "==".
This could be used on a function that works with data from the code, and data from the database, if you are validating a value from the code it will likely be a boolean, but if you are getting the data from a database then depending on the way your database is configured it could be retrieved as a string
Makes sense, its about keeping balance and knowing when to use which but when it comes to best practices i think === is a go to approach in most cases.
I think both operators have its uses, but because it makes the code more clear in most cases you would want to use the strict equality operator.
It promotes more explicit code comparisons, and if some variable you're checking can return both undefined and null, 0, its more likely that the variable or data is not correct or not defined well.
I wouldn't ban its use, but I'd discourage it.
When deciding on an equality operator, the question we should be asking ourselves is "Am I happy if type coercion potentially occurs before we perform this equality comparison?". If the answer is "no" - and almost always it will be - then use the strict equality operator. If the answer is "yes" and you understand the equality operator well, go ahead.
However, I suspect that often there may be clearer and more maintainable ways of approaching things than by using the equality operator. For example, if you're happy for
-10
and10
to be considered equal, how about usingMath.abs()
?Math.abs(x) === Math.abs(y)
is clearer and more maintainable down the road than
x == y