Notes On Equality In JavaScript

Chiamaka Nwolisa
mPharma Product & Tech Blog
3 min readDec 3, 2018
Weary skies by me

JavaScript is a different language. No matter what language you learnt before JS, it is bound to make you stare in disbelief at how things are done. One of the quirks we are going to demystify is the concept of equality.

In many programming languages, if you want to check equality, you use ==. Double equals exist in JavaScript but if you aren’t aware of its quirks, you can get blindsided by it and I’m here to help avoid that from happening.

A very popular misconception about equality in JS is that:

Loose equals `==`checks values for equality and strict equals `===` checks both the value and the type for equality.

What actually happens is:

Loose equals `==` allows coercion while strict equals `===` disallows coercion.

Allow me to illustrate:

3 == '3'; // true3 === '3'; // false

Huh, that’s weird. We know that the number 3 is not equal to the string 3 so what the hell is going on?

With loose equals, the JavaScript engine sees that both values are not of the same type so it goes ahead to implicitly coerce one or both of the values.

How does this “coercion” work? Is the string coerced to a number or is the number coerced to a string?

According to the ECMAScript Language Spec; The Abstract Equality Comparison Algorithm —for the comparison x == y, if Type(x) is a Number and Type(y) is a String, return the result of the comparison x == ToNumber(y) and if Type(x) is a String and Type(y) is a Number, return the result of the comparison ToNumber(x) == y.

This means that the String value is always coerced to a Number and then compared. So essentially, JS coerces the string ‘3’ to a number and 3 == 3 is true. But this is not the case with strict equals === because it disallows coercion. So the above example compares the Number 3 to the String 3 and since coercion is not allowed, it evaluates to false.

Another example:

const a = null
const b = undefined
a == b; // true
a === b; // false

null and undefined, when compared with loose equals ==, coerce to each other and no other values in JS. The coercion between null and undefined is safe and predictable. It’s recommended to use coercion to allow both values to be treated as the same value for comparison purposes.

Knowing this, we can thoughtfully use loose equality to do our bidding:

const a = performSomeAction();if (a == null) {
// if a is null or undefined, then this block of code would be executed
....
}

This is the explicit form of the check which utilizes strict equals ===

const a = performSomeAction();
if (a === undefined || a === null) {
...
}

They both achieve the same thing. This is an example where utilizing implicit coercion improves code readability in a reliable way*

When it comes to objects, loose equals ==and strict equals ===behave identically. The two values being compared are only equal if they are both references to the exact same value, no coercion occurs.

const a = { name : 'Chi' };const b = a;const c = { name : 'Chi' };a == b; // truea == c; // falsea === b; // truec === a; // false

When deciding between using loose equals and strict equals, ask yourself if you want coercion or not? If you want coercion, use `==`, but if you do not want coercion, use `===`.

*This is the only situation where I would allow loose equality in my codebase

--

--