Dark Truth of Abstract Equality (==) & Strict Equality (===) ... (Hidden Facts with proof)
Introduction
Comparison operators are used in conditional expressions to determine which block of code executes, thus controlling the program flow. Comparison operators compare two values in an expression that resolves to a value of true or false.
In Javascript also we have many comparison operators but but out of those all, there are two comparison operators which are almost similar but differ by very few thin lines drawn by developers of Javascript. I hope you guessed it right I am talking about ==
& ===
operators. These two operators have names as well one is having fixed name i.e strict equality operator ===
& second one has two names just like the official name and nickname i.e Abstract equality operator ==
. People also call ==
as a loose equality operator. Both operators check equality but with certain differences. Checking equality is so simple but people always get confused about these two operators.
"==" equality checks for value
"===" equality checks for both value and datatype.
Abstract equality (==
)check only values and Strict equality (===
)checks both type and values. Is it Correct ???
Many of you will think this is the correct statement and there are a bunch of articles and blogs you will see this is the correct statement,
But actually, the answer is NO NO NO NO, this is an absolutely wrong statement. This is the misconception many people have. Am I proving it wrong no The actual JS Documentation proves it wrong and I am going to brief here everything you need to know about ==
& ===
, So let's go step by step let's understand first Abstract equality and Strict equality and then see the difference in working of both.
const myRollNo = 23;
console.log(typeof myRollNo); /* "number" */
const str = "23";
console.log(typeof str); /* "string" */
console.log(myRollNo == str); /* true */
console.log(myRollNo === str); /* false */
With the above approach, it seems that there is an issue with Abstract Equality ==
and many will say there is an issue with this but
When there is a difference between what we think and what JS Does, there appears the bug
Now Let's understand how things work so basically Type Coercion is a fundamental pillar of Javascript and how it works behind the scene.
What the hell is Type Coercion Now ??
Javascript has 4 fundamental pillars which make javascript a best in the game i.e
Coercion
Object Oriented Programming
Scopes
Asynchronous Programming
Type coercion is nothing but the conversion of data types.
Type Coercion can happen in two ways -
Explicit Coercion - When there is a change in the data type intentionally(on purpose) by the author of the code, then it is said to be explicit coercion.
const num = 23; const strNum = String(num); // '23' console.log(typeOf(num)); // Number console.log(String(num)); // '23' console.log(typeof(num)); // Number; console.log(Number(strNum)); // 23 console.log(typeOf(strNum)); //String
Implicit Coercion - When there is a change in the data type happens automatically by the language itself. Javascript implicitly performs automatic type conversion as needed.
const name = 'Akash'; const age = 22; console.log(name+age); // Akash22 /* In the above code we are addinng two variable name and age. If one of the operand is a string then other operand is automatically converted to the string data type. In the above code, name data type is a string and age data type is number which is converted to string automatically by implicit coercion. */
Abstract Equality ==
Abstract equality operator ==
is also referred to as a loose equality operator returns a boolean value of true
or false
based on comparison i.e if both values are equal it returns true
or else returns false
. That's it that's the working of an Abstract equality operator you must be thinking it's almost similar to whatever we read in other blogs but wait my dear readers.
Real working of Abstract equality works differently :
- It checks the Type of both operands and if the type is the same it performs a Strict Equality operation over those two operands which we will see later.
If the type of both operands is not the same it performs Type Coercion Implicitly based on Algorithm which is as follows:
DISCLAIMER - Don't get overwhelmed by word algorithim just think it as bunch of steps which gets followed internally
These are the steps that get followed internally when Abstract Equality ==
used over operand x & y when we use x==y
So what happens here when we use
==
operator, it performs a type check as shown in the first step. If both the type is same Javascript internally calls Strict Equality Comparison Steps x===
y.If the left operand i.e
x
here isnull
and the right operand i.ey
isundefined
then it returnstrue
.If the left operand i.e
x
here isundefined
and the right operand i.ey
isnull
then it returnstrue
.That's why when we do
console.log(undefined==null)
we gettrue
but I saw many people tells it as a weird behaviour of Javascript. Now with the above steps, we got the understanding this is no weird behaviour in spite it's mentioned in such a way that it will returntrue
.The most awaited point came up what if one operand is a number and one operand is a string so if we see the 4th step in the above image we can see that if the left operand i.e
x
is of typenumber
and right operand i.ey
is of typestring
,
Js does internal type coercion and converts the right operand which is thestring
data type to anumber
type and then after type conversion, it returns the result ofx == y
& again and now bothx
andy
type is the same i.enumber
type then it will perform strict equality===
over x and y as explained in step 1.Same as above what if again one operand is a number and one operand is a string so if we see the 5th step in the above image we can see that if the left operand i.e
x
is of typestring
and right operand i.ey
is of typenumber
,
Js does internal type coercion and converts the left operand which is thestring
data type to anumber
type and then after type conversion, it returns the result ofx == y
& again and now bothx
andy
type is the same i.enumber
type then it will perform strict equality===
over x and y as explained in step 1.What if one operand is
Boolean
type and another operand isnon-boolean
(string,number,undefined,null,symbol)
type value then javascript internally does implicit type coercion and converts boolean data type value.If the left operand i.e
x
isBoolean
type value and Y isnon-boolean
(string,number,undefined,null,symbol)
type thenx
will be converted internally to aNumber
type value and thenx == y
is performed and the result is returned. (Refer to the 6th point in the above image)If the left operand i.e
x
isnon-boolean
(string,number,undefined,null,symbol)
type value and Y isBoolean
type value theny
will be converted internally to aNumber
type value and thenx == y
is performed and the result is returned.(Refer to the 7th point in the above image)
console.log(true == 'true') // false /* Many places you will find the explanation that boolean true will be type coercied to string and then check will happen but that is wrong explanation what happens here let's see this : 1 - both types are not equal so step 1 is ruled out 2 - one operand is boolean so now boolean operand will be converted to number type so Number(true) --> 1 and now check will happen with 1=='true' 3 - Now again when 1 == 'true' is checked 3.1 Type is not same so step 1 will be ruled out again. 3.2 One type is number and other type is string so string type will be converted into number and when we convert string 'true' to a number Number('true') it returns NaN (not a valid number). and again 1== NaN get's performed. 4 - Now see 1 is of type number and NaN is also of type number so both are same type and now since both are of same type strict equality operation get's called 1 === NaN and since left operand i.e 1 is not equal to right operand i.e NaN , hence it returns result as False. */ /* I hope I was able to explain the example well if any doubts please do put it out in comment section I will try to resolve it */
The 7th point explanation is the same as the 6th point.
So what happens when one of the operands is of type
String
,Number
orSymbol
orBoolean
gets compared with anon-primitive
value i.e with an object then the Javascript converts thenon-primitive
value to aprimitive value
using an abstract operation let's not get deep dive into that as it's in itself a big discussion which I will discuss in later blogs. so it converts the object into a valid primitive value and then performs abstract equality (==
) over it.If left operand i.e
X
isString
orNumber
orSymbol
& right operand i.ey
is anobject
thany
will be converted intoprimitive
data type and then it performsx==y
.If left operand i.e
X
is anobject
& right operand i.ey
is anString
orNumber
orSymbol
thanx
will be converted intoprimitive
data type and then it performsx==y
.
Now Let's Move to Strict Equality ===
Operator -
Strict Equality Operator ===
Strict equality is the most widely used in the codebases. The main reason for its high usage is due to the lack of knowledge of people regarding Abstract equality so since now we have a better understanding of Abstract equality ==
let's decipher how Strict Equality works -
So this is the basic working of ===
operator :
It checks the type of both the operand and if the type of both operands is different then it returns
false
.Since both the operand are of the same type then If one operand is
Number
If
x
is NaN it returns false.If
y
is NaN it returns false./* If anyone of the operand is NaN then it returns false. */ /* So You might have come across this question console.log(NaN ===NaN) prints false why ? */ /* Ans - The reason is simple since both left operand and right operand is of same type Number then it checks if any of the operand is NaN it returns false. Disclaimer - NaN is the only value of number type which is not equal to itself */
If the left operand
x
and right operandy
are both of the same value it returns true.If the left operand i.e
x
is0
and the right operand i.ey
is-0
it returns true.If the left operand i.e
x
is-0
and the right operand i.ey
is0
it returns true.If none of the above steps is validated then it returns simply
false
.
So Now we got an understanding of both Abstract Equality ==
& Strict Equality ===
.
We understood how things work and Basically, we demystified the fact that Javascript is not weird it's the beauty and magic of Javascript and its pillar.
Conclusion
So now we know very well that nothing in Javascript is weird. Some people think Coercion is a boon to Javascript but according to me it's not a boon if we know and understands it very well.
Now a valid point comes up when to use ==
& when to use ===
?
so we see in large codebases and in many organizations, we use Strict Equality ===
which is a very good thing to do. According to me if we are not sure on what data value we are applying equality checks then it's recommended to use ===
.
If you want to experience power or coercion you can use ==
.
I hope after reading this your confusion regarding ==
& ===
will get over still, if you have some doubts please ask in the comment section, and I'll be happy to clear your doubts.