DEV Community

Why You Should Never Use (==) in JavaScript

Quratulaiinn on October 30, 2023

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 co...
Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

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.

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

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.

data = await fetch(...)

if(data.id == 1) // doSomething
Enter fullscreen mode Exit fullscreen mode

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 float 1.0, nor you will obtain any benefit by doing:

data = await fetch(...)

if(Number.parseInt(data.id) === 1) // doSomething
Enter fullscreen mode Exit fullscreen mode

As a rule of thumb, use === whenever no conversions are expected to take place to avoid confusion.

E.g.

if (typeof x === "function") { 
  ...
}
Enter fullscreen mode Exit fullscreen mode

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.

Collapse
 
kiss_code profile image
kis.stupid

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.

Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

Yes!
You can even shorten that in most cases and simply check

if (isSomething)
Enter fullscreen mode Exit fullscreen mode

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:

undefined == true // false
undefined == false // false
null == true // false 
null == false // false
'a' == true // false
[1] == true // true
[2] == true // false
Enter fullscreen mode Exit fullscreen mode

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:

const checkTruthyness = (val) => !!val;
Enter fullscreen mode Exit fullscreen mode

or, if you prefer it

const checkTruthyness = (val) => Boolean(val);
Enter fullscreen mode Exit fullscreen mode

so you can

checkTruthyness(1) // true
checkTruthyness(3) // true
checkTruthyness('a') // true
checkTruthyness('') // false
checkTruthyness([]) // true
checkTruthyness(null) // false
checkTruthyness(undefined) // false
Enter fullscreen mode Exit fullscreen mode

or directly

if (!!isSomething)
Enter fullscreen mode Exit fullscreen mode

or

if (Boolean(isSomething))
Enter fullscreen mode Exit fullscreen mode

Hope you find better names than I did, tho 😂

Best regards

Thread Thread
 
kiss_code profile image
kis.stupid • Edited

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.

true == "true" // true
true == "1" // true
Enter fullscreen mode Exit fullscreen mode

Or did I use it for everything that is not true?

false == "true" // false
"0" == "true" // false
undefined == "true" // false
null == "true" // false
"" == "true" // false
Enter fullscreen mode Exit fullscreen mode

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

Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

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(data.view_id == 2) 
Enter fullscreen mode Exit fullscreen mode

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:

if(data.view_id === 2) 
Enter fullscreen mode Exit fullscreen mode

now if the backend returns "2" instead of 2... 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:

if(Number.parseInt(data.view_id) === 2) 
Enter fullscreen mode Exit fullscreen mode

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 😂

if(2 === Number.parseInt(data.view_id)) 
Enter fullscreen mode Exit fullscreen mode

jokes aside, In this use-case,

  • the == solution is more resilient and easy to read
  • the === one is less resilient and equally easy to read,
  • the parse + === 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 😅😂

Collapse
 
buchslava profile image
Vyacheslav Chub • Edited

Agree!

const a = 1;
const b = "1";
console.time("first");
for (let i = 0; i < 999999999; i++) {
  a === b;
}
console.timeEnd("first");

console.time("second");
for (let i = 0; i < 999999999; i++) {
  a == b;
}
console.timeEnd("second");
Enter fullscreen mode Exit fullscreen mode

The result:

first: 741.86ms
second: 6.926s
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dsaga profile image
Dusan Petkovic

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

Collapse
 
buchslava profile image
Vyacheslav Chub

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.

Thread Thread
 
dsaga profile image
Dusan Petkovic

Yea, good to know that it does make a difference

Collapse
 
quratulaiinn profile image
Quratulaiinn

Thank you for this addition.

Collapse
 
lopis profile image
João L.

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

Collapse
 
miketalbot profile image
Mike Talbot ⭐ • Edited

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

Collapse
 
lopis profile image
João L.

Funny but I think the meaning is a bit lost in this one.

Thread Thread
 
miketalbot profile image
Mike Talbot ⭐

Hmmm, made sense to me. Though I guess it's pushing less common English to make the rhyme.

Thread Thread
 
lopis profile image
João L.

I felt like the opposite from "And refrains from a neat, clean design" was what I was hinting at

Collapse
 
dsaga profile image
Dusan Petkovic

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.

Collapse
 
joaomadeiraxyz profile image
João Victor

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 "==".

Collapse
 
joaomadeiraxyz profile image
João Victor

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

Collapse
 
quratulaiinn profile image
Quratulaiinn

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.

Collapse
 
budokans profile image
Steve Webster • Edited

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 and 10 to be considered equal, how about using Math.abs()?

Math.abs(x) === Math.abs(y)

is clearer and more maintainable down the road than

x == y