Hello awesome devs of the internet ๐,
In this blog post we shall discuss and learn more about one weird problem faced by JavaScript developers (beginners and some advanced too ๐
). Below we break down the complexity of equality checks in JavaScript both at the operator level and at the object level.
Equality Checks !
Equality checks is one of those things we all end up doing generally due to the fact that we canโt avoid the famous conditional if - else
statement unless we try really hard.
Equality Comparators
The most basic equality comparators are strict equality(===) and loose equality(==) which shall both be reviewed below. Some more complex comparators exist such as Object.is() which we might speak about in another blog if you are interested in.
The difference between ==
and ===
often confuse a lot of new JavaScript developers since they look alike and most of the time give us the same result โ until it doesnโt.
One of the conveniences in JavaScript is that it will automatically coerce any value being referenced in a boolean context to a boolean value. But there are cases where this can be as confusing as it is convenient.
Briefly,
The Strict Equality, ===
basically compares two values as is i.e. without any type conversion. If the values youโre comparing are numbers, then they are considered equal if they are the same and not NaN
.
This is somehow due to the fact that the ===
doesnโt know if the compared value has the same type or not.
on the other hand, Loose Equality ==
converts values into a common type before the comparison is made. as such the equality of the compared objects is determine on the base of their conversion to the same type.
here is what i mean :
with strict equality check
console.log(404 === 404); //true => type and value is same
console.log(404 === '404'); //false => type is not the same
console.log('404' === '404'); //true => type and value is the same
meanwhile with loose equality check,
console.log(404 == 404); //true => both have the same value
console.log(404 == '404'); //true => after conversion, both are equal
console.log('404' == '404'); //true. => No conversion needed but value are similar nevertheless
Some of the following, for example, have been known to bite many JavaScript developers at least once :
// All of these evaluate to 'true'!
console.log(false == '0');
console.log(null == undefined);
console.log(" \t\r\n" == 0);
console.log('' == 0);
As these examples demonstrate, the rules of type coercion can sometimes be easy to visualize. Accordingly, unless type coercion is explicitly desired, itโs typically best to use ===
and !==
(rather than ==
and !=
), so as to avoid any unintended side-effects of type coercion (conversion before equality check ) . (==
and !=
automatically perform type conversion when comparing two things, whereas ===
and !==
do the same comparison without type conversion.)
Let's get deeper
To better understand let's get through many examples of different nature. you will notice that these equality checks might behave in an unexpected way and therefore learn from this, here we go...
1- With objects
let myObject = new String('item');
let myString = 'item';
console.log(myObject == myString );
//returns true. => after conversion, semantically, it's the same.
console.log(myObject === myString );
//returns false. => there is no conversion and type is different despite having the same value.
2- With Binary
Boolean values first converted into to 1 or 0 by ==
. therefore :
console.log(true == 1); //returns true
console.log(true === 1); //returns false => types are different
3-String vs Boolean
Here, the string value gets converted into a numeric value before equality check:
console.log(true == 'true');
//returns false => string can't be transformed into a number
console.log(true == '1');
//returns true =>'1' can be converted into a numeric value and 1 equals 1
4-Objects vs boolean
Guess what?, here the object gets converted into a primitive type and if it ends up being a number, then it has a chance of throwing the correct and expected output.
let x = new String('1');
let y = new String('true');
console.log(x == true); //true. x can be converted to a number
console.log(y == true); // false. y can't be converted into a number
//both console logs will return false if === is used because type is different.
Bonus
Since weโre talking about type coercion and comparisons โ itโs worth mentioning that comparing NaN
with anything (even NaN!
) will always return false
. You therefore cannot use the equality operators (==
, ===
, !=
, !==
) to determine whether a value is NaN
or not. Instead, use the built-in global isNaN()
function:
console.log(NaN == NaN); //return false
console.log(NaN === NaN); //return false
console.log(isNaN(NaN)); //return true
Conclusion
Hopefully this has cleared up any confusion or mysterious differences between == and ===, and help reduce potential bugs caused by equality operators. Sometimes things look the same but the situation and scenario in which they are use also determine their final outcome.
So a main point to retain from this blog is:
The big difference between strict and loose equality is that the later converts values into a common type before the comparison is made. While ===
does no conversion at all and performs the comparison as is, ==
converts the value and determines sameness based on that.
Thanks for your kind attention.
Top comments (0)