Photo by Blake Connally on Unsplash
Understanding “==” (Abstract Equality) and “===” (Strict Equality) in JavaScript
A lot of people including me had a misconception that in JavaScript “==” doesn’t check type and “===” does, but sometimes we have to unlearn some things.
So before understanding these two equalities we have to understand Coercion.
What is Coercion
Coercion in JavaScript is the automatic conversion of a value from one data type to another data type.
JavaScript has two types of coercion
Explicit
Implicit
Explicit coercion happens when the programmer explicitly converts a value from one type to another, using functions such as Number()
, String()
, and Boolean().
Implicit coercion, on the other hand, happens automatically when JavaScript converts a value to another type behind the scenes.
Examples:-
Implicit Coercion uses some set of operations that are present in the ECMAScript but they are not available for usage in the ECMAScript. ie., as developers we cannot use these operations directly. ECMAScript defines several abstract functions including Type, ToPrimitive, ToString, ToNumber, and ToObject for defining the behavior of language constructs and operations.
For the time being let's understand what are ToPrimitive and ToNumber.
ToPrimitive is a built-in abstract operation in JavaScript that converts a value to a primitive value.
Here's how ToPrimitive works:
If the input value is already a primitive value, return it as-is.
Otherwise, if the input value has a
valueOf
method that returns a primitive value, call that method and return the result.Otherwise, if the input value has a
toString
method that returns a primitive value, call that method and return the result.Otherwise, throw a TypeError.
In this example, obj
is an object that has both a valueOf
method that returns the number 42
, and a toString
method that returns the string "foo"
. When we use the +
operator to add obj
and 5
, the ToPrimitive
operation is called on obj
, with a default hint of "number". The valueOf
method is called first and returns the primitive value 42
, which is then added to the number 5
, resulting in the number 47
.
ToNumber is a built-in abstract operation in JavaScript that converts a value to a number. ToNumber takes an input value as its argument and returns a numeric value based on the type and value of the input.
Here's how ToNumber works:-
If the input value is already a number, return it as-is.
If the input value is a string, attempt to convert it to a number using the following rules:
If the string begins with a valid numeric literal (e.g. "123", "-456", "3.14"), parse it into a corresponding number value.
If the string does not begin with a valid numeric literal, or if it contains characters that cannot be parsed as part of a number (e.g. "foo", "123abc"), return
NaN
.
If the input value is a boolean, return
1
if the value istrue
, and0
if the value isfalse
.If the input value is
null
, return0
.If the input value is
undefined
, returnNaN
.If the input value is an object, attempt to call its
valueOf
method. If the result of the method call is a primitive value, return the result after performingToNumber
on it. Otherwise, call the object'stoString
method and return the result after performingToNumber
on it.Otherwise, throw a TypeError.
I know it's overwhelming but bear with me 😁
So these are the set of rules which ECMAScript follows for Abstract Equality Comparison.
As you can see from point number 1 "==" actually checks the type of the numbers which it is comparing, if it is the same then it returns the result after following the rules which Strict Equality Comparison follows.
Now if we follow point number 2 and 3
we got to know why "null == undefined" is true.
Let's understand point number 4 and 5
Here if any of the two numbers is a string then ECMAScript will prefer a number comparison and converts the string into a number and then do the comparison.
Example:-
const a = 10;
const b = "10";
const isEqual = a == b;
Here isEqual will result in true, as the string "10" is implicitly coerced to the number 10.
Point number 6 and 7 says that
If after doing the above operations, any of the two numbers become boolean or if we are directly doing abstract equality in boolean then it will follow these steps.
Note:- 'true' is converted to '1 ' and 'false' is converted to '0' during coercion.
Example:-
true == 1; // returns true
false == 0; // returns true
true == "1"; // returns true
false == ""; // returns true
true == "true"; // returns false
false == "false"; // returns false
At last, let's understand points 8 and 9
It tells us that if any of the two is an object and the others are string, number or symbol then it will convert the object to a primitive value before doing abstract equality.
Now we understood the rules of Abstract Equality let's see the rules which Strict Equality comparison follows
So in Strict Equality, if the type of x is different from the type of y it simply returns false, no coercion is going to happen.
Now things get interesting from point2
we can see if x or y any of them is NaN then it simply returns false as a result we got the answer to why NaN is not equal to NaN.
and same for the why +0 is equal to -0
For the 3rd rule please read below:-
here for objects, we have to take some extra note
For Example:-
here we can see that obj1 === obj2 is giving false although the key-value pair is the same, this is because they are 2 different objects pointing/present in a different memory location, so if we compare the same memory objects like obj1 === obj1 as they are present in the same memory location it will result in true.
Note:*- We often say JavaScript is weird if we don't understand something about it, due to this it is one of the most hated languages but we also have to understand it is the most loved language also (Quoted Akshay Saini😉). If we know the rules of the language on which it is based then we understand the language better.*
Peace☮
Credits: - I have referred to the official docs of ECMAScript for the rules which you are seeing in the blog.
Special Thanks! to Sanket Singh by following his lessons I can go this deep into the world of Javascript.