One of the most common interview question that every Javascript developer has encountered in their career is "What is the difference between ==
and ===
". Well, I guess most of them reading this would already have come up with the most common answer which is
''=='' compares value and "===" compares both value and type.
What if I say that this isn't the right answer ๐. Let's dive deep and understand what's happening behind the scenes. According to the ECMA Script specifications, both ==
and ===
checks the type of the variables. If the types are same, both ==
and ===
work exactly the same post which they return true
or false
based on the values. It's when the types of the variables are not matching, both differ. ๐ณ
When the types are not same, ==
does an implicit coercion while ===
directly returns false
. Implicit Coercion is nothing but the conversion of variable from one type to another.
Based on the ECMAScript specification, whenever Javascript encounters a ==
operator, an abstract operation called IsLooselyEqual ( x, y )
gets invoked. Similarly, when it encounters a ===
operator an abstract operation called IsStrictlyEqual ( x, y )
gets executed. I understand this might be too much to digest at the moment but lets try to understand both these operations with the help of some code snippets. We won't be covering all the cases of the operation, rather we would try to address some of the common scenarios that we encounter normally.
Case 1:
var stringOne = '1';
var numberOne = 1;
if (stringOne == numberOne) {
console.log("IsLooselyEqual(x,y) is invoked");
}
In the above code snippet, we have two variables -stringOne
and numberOne
of types string
and number
respectively. After which we have a conditional statement where we check if stringOne
and numberOne
are equal using the ==
operator. As soon as the Javascript encounters ==
operator it applies the IsLooselyEqual(x,y)
abstract operation. According to this operation, following steps are done.
It checks if the types of
stringOne
andnumberOne
are same or not. If they are same, it returns a value by applyingIsStrictlyEqual(x, y)
(Step 2 of the actual algorithm) abstract operation wherex
would bestringOne
andy
would benumberOne
respectively.If the types are not same, it checks if the type of
stringOne
is aString
type and type ofnumberOne
is aNumber
type (Step 6 of the actual algorithm) . Since it's true, it convertsstringOne
variable into aNumber
type by applying theToNumber(x)
abstract operation.ToNumber(x)
is another abstract operation which converts the variable to aNumber Type
variable. In this scenario,stringOne
would bex
, applyingToNumber(x)
operation would beToNumber(stringOne)
wherestringOne
would be converted fromString
type toNumber
type based on this . After which it returns the value by applyingIsLooselyEqual(x, y)
abstract operation again where now bothx
andy
are of the same type.Since both are of the same type, it returns the value by applying
IsStrictlyEqual(x,y)
abstract operation.IsStrictlyEqual(x,y)
checks if the types of bothx
andy
are the same. If the types are same, it checks the value of bothx
andy
. If the values are also the same, then the operation would return atrue
else it would return afalse
.
Case 2:
var arrayOne = ['1'];
var numberOne = 1;
if (arrayOne == numberOne) {
console.log("IsLooselyEqual(x,y) is invoked");
}
In the above code snippet, we have two variables arrayOne
and numberOne
of types object
and number
respectively. After which we have a conditional statement where we check if arrayOne
and numberOne
are equal using the ==
operator. As soon as the Javascript encounters ==
operator, it applies the IsLooselyEqual(x,y)
abstract operation. According to this operation, following steps are done.
It checks if the types of
arrayOne
andnumberOne
are the same or not. If they are the same, it returns the value by applyingIsStrictlyEqual(x, y)
abstract operation wherex
would bearrayOne
andy
would benumberOne
respectively.If the types are not the same, it checks if the type of
arrayOne
is anObject
type and type ofnumberOne
is aString, Number etc
type (Step 12 of the actual algorithm) . Since it's true, it converts theObject
type variable into aPrimitive
type by applying theToPrimitive()
abstract operation. This operation, in brief, tries to convert theObject
type to aPrimitive
type which would be either aString
or aNumber
type (ToPrimitive).It then returns the value by applying
IsLooselyEqual(x, y)
operation by passingx
andy
and repeats the same steps till the types of bothx
andy
are equal or whenIsLooselyEqual(x, y)
operation returnsfalse
.For the above code snippet below is the explanation on why it prints the console statement
var arrayOne = ['1'];
var numberOne = 1;
/*
1. it checks if typeof arrayOne equals typeof numberOne
2. if they are not the same it applies the ToPrimitive abstract operation on 'arrayOne'
as it's type is an Object.
3. On applying the above operation, it becomes a primitive type which is a `String`
type in this case. Applying the String() to any array object will strip the '[' and ']' and
return the elements as a string value. In this case String(['1']) = '1'. This is what
happens on applying `ToPrimitive` operation.
4. After the above step, it applies 'IsLooselyEqual(x,y)' operation again and repeats the
steps.
6. Since now the `arrayOne` is of `String` type and `numberOne` is of
`Number` type, it applies the `ToNumber` abstract operation on `arrayOne` and
returns the value by applying `IsLooselyType(x,y)` operation.
7. As the types are the same, it will return the value by applying `IsStrictlyEqual(x,y)`
which will return `true` and hence prints the console statement present inside the
block.
*/
if (arrayTypeOne == numberTypeOne) {
console.log("IsLooselyEqual(x,y) is invoked");
}
Case 3:
var objectOne = [];
var booleanOne = true;
if(objectOne) {
console.log("This check whether array is empty or not won't work !!")
}
In the above code snippet, we have two variables objectOne
and booleanOne
of types object
and boolean
respectively. After which, we have a conditional statement where we check if objectOne
is true
. As soon as Javascript encounters this, it applies a new abstract operation called ToBoolean(x)
. This operation converts the variable to a Boolean
type depending on the reference table as shown below (ToBoolean) .
Based on this table, since our variable is of type Object
it would return us true
irrespective of whether the array is empty or not. This is the main reason why we need other parameters while comparing Object
types. In our case, since we clearly know its an array object, we could use the length
property. Now we can refactor the above code in the following way for checking emptiness.
if(objectOne.length) {
console.log("You won't see me since I am empty !!")
} else {
console.log("You saw me since I am empty !!")
}
By now I hope you understood how Javascript treats the ==
and ===
operator and cases when they are actually different. Above mentioned were just few scenarios out of many. If you are really interested to dig deeper, I would recommend you to go through ECMA Specifications where you will find the complete implementation of both IsLooselyEqual(x,y)
and IsStrictlyEqual(x,y)
abstract operations. I would also encourage you to read this book if you haven't - You Don't Know JS by Kyle Simpson.
Thank you
Hope you enjoyed this read on ==
and ===
operators and how comparisons works in Javascript. Now you can make use of this knowledge to really ace the above question in your upcoming interviews ๐. Let me know your thoughts in the comment section down below. If you feel this article is useful, please do show your love and share this to your fellow beings who could make maximum use of this. Always feel free to connect with me via twitter, linkedIn or email. Happy to help in all ways possible ๐
Until we meet again, The Mallu Dev signing off ๐ Cheers ๐ฅ