Do strict equals do what we thought?
By: Alen Vlahovljak
Tags: JavaScript, Javascript Tips, Programming, Javascript Development, Web Development

Do double equals solve our problems?

You may sometimes be wondering why we aren’t having problems with arithmetic operators or conditional statements, but with equals. The biggest coercion which people struggle with is an equality checking.

In this story, I want to dig deep into some issues which are related to differentiating between loosely and strict equals. There is a big lie when we are comparing ‘==’ and ‘===’:

MYTH: Difference between ‘==’ and ‘===’ is that ‘==’ checks the value (loose equality) and ‘===’ checks the value in the type (strict equality).

That notion is remarkably common. But unfortunately, it’s not right. If you want to understand this process and why this is a false assertion, you have to understand your code. You have to start thinking as JavaScript do. Let’s take a look at the specification:

Abstract Equality Comparison (source: ECMAScript Standard)

This part is called the Abstract Equality Comparison, and it’s responsible for defining the way on which loose equals works. That is the most reliable evidence to prove that the loose equals do not only check the value.

Conclusion: The first rule says that if the two values have the same type, then it’s going to perform a strict equality comparison.

Now we can unravel the myth that the difference between these two equalities is whether the types are the same. No, that’s not the truth! They both examine types, but the way of using that knowledge is a bit different.

You have to remember that the first and only authoritative knowledge source of any technology is documentation.

Adopting the right mental model is a fundamental thing. Don’t waste your time on reading unreliable stories and books about double equals. They seldom reference to the only reliable source - documentation.

Documentation is not hard to understand. It’s just a bunch of conditional statement which you can understand since you’re a developer. The next example will separate the facts from rumours:

On the first line, we have a string "Jamie" which is assigned by variable person1 . On the next line, I create a copy of the first variable. When I try loose and strict equality, it says that they are equal in both cases. It turns out that when the types match, then they do the triple equals.

Conclusion: The double equals and the triple equals are the same when the type match. When the types match, do the triple equals.

It’s an excellent thing to pair types as much as possible, but that doesn’t mean you won’t have coercion. It’s impossible to avoid coercion, but you can reduce the number of coercions.

You have to design your code to be clear and consistent. You have to have a sense when writing your algorithm. It’s a bad practice to have no idea about types. Even if you don’t know it doesn’t mean that it has to stay that way. Code redesign is the best solution in this case.

Do triple equals do some superior work?

You may be wondering what the heck is triple equals doing? It’s checking types, and that is it. It doesn’t matter when the values are if the types are different. It’s a kind of bypass which stop the algorithm when the types are different (returning false).

So, what is the difference between double and triple equals? The answer may surprise you:

The real difference between strict equality and loose equality is whether or not we’re going to allow any coercion to occur.

Let’s see the documentation to make things clear:

Strict Equality Comparison (source: ECMAScript Standard)

What does Strict Equality Comparison do if the types are the same? It does what the documentation says (image above). For example: if we compare NaNs, it’s going to return false. The next great example is if we compare zero with negative zero - it’s going to return true.

We have a few caveats which we need to think about (like two examples above), but that’s only when the types already match.

Conclusion: They both check types, but strict equality stops earlier.

Things are a bit different for objects. I’ll give an example:

We have two different objects. How they are different, they have the same properties? They are not the same objects.

Don’t fall in the trap and get confused with JS engine that is not checking the full object (comparing the structure of objects), but comparing on which object(s) are variables pointing (referencing). I’m not sure that any language does something else than identity comparison.

If movie1 and movie2 are object reference to the same object, it’s going to return true. In the above example, that is not the case because the variables are pointing to distinct objects.

In our example, the outcome is the same. Loose equals are going to allow coercion when types were different, and strict equals are going to disallow coercion when the types are the same.

Clarification

It’s crucial to know which mechanisms are participating in each operation. Ask yourself a question: I know the types, do I need to use coercion; is it helpful? There is no universal law which encourages us to judge whether to use coercion or not.

Sometimes you have to think about corner cases, so you may ask yourself: Is it safe to use coercion? You have to out of the box thinker. In my opinion, choosing between strict equals and loose equals is about code intelligibility and cleanness.

Using triple equals is a sign that you don’t know which types are you using in a particular case, and using triple equals is a kind of protection of potential bugs.

The only case I use triple equals is in tests but as a temporary solution. When I’m not sure about which types come into play, I take a safe approach and use triple equals to secure from potential logic bugs. After I do some code refactor — fix root problems, I get back to tests and revert to double equals.

It’s regularly a good practice to know with which types are you working with because that leads to a better code understanding, with less unpredictable cases.

Conclusion: Knowing which types are you using in particular case lead to a better codebase.