When I started learning JavaScript, one thing that amazed me was the use of three equals to symbols to compare variables. As someone who learnt C++, Java and python before JS, this was really confusing.
I also remember the frustration when my code wasn't working because I used a wrong operator. I ended up wasting an hour trying to find a bug. hehe.
What are those called? ๐ง
The double equality operator (==) is called 'Loose Equality' but sometimes also referred to as 'Abstract Equality' operator. Triple equality operator (===) is called as 'Strict Equality' operator and some people love to call it 'Identity operator'.
Why they exist? ๐ค
Both have similar purpose, that is comparing variable at right side of the operator with the left one and compute the output. The result is Boolean true if both variables are same and false if they are different.
What's the difference, you might ask! Here comes the JavaScript with its bright yellow color to stop you right there...
Exact difference ๐ฒ
Though the purpose seems similar, if we go under the hood and see how they function; we get the idea about their individual existence.
The loose equality operator first performs type conversions, if necessary. Then it computes the result based on the new converted variable.
let a = 20
let b = "20"
console.log(a == b) // Expected output: true
Here, variable b
of data type string
first gets converted into number data type and then gets compared with a
which already has a data type of number.
Identity operator in other hands, does not performs any type conversion and presumes that both variables have same data type.
let a = 20
let b = "20"
console.log(a === b) // Expected output: false
Here the answer is false because data types of variables being compared are different and not getting converted either. Let's dive deep...
Loose Equality Operators
By now, we know this twin pair does type conversion before comparing variables. But what happens when we compare between 0, empty string, null, undefined and Booleans with each other? This is where it gets weird and difficult to understand. Let me explain it by example itself:
console.log(0 == false) // true
console.log(0 == "") // true
console.log(0 == null) // false
console.log(0 == undefined) // false
console.log(null == undefined) // true
console.log(false == "") // true
Huh! take a breath. things are about to get worse.... because now we will deal with objects and strings!
Comparing objects with loose equality
When two objects are being compared, the result is true
if and only if both variables are referencing to same object.
let obj1 = { "name": "foo" }
let obj2 = { "name": "foo" }
let obj3 = obj1
console.log(obj1 == obj1) // true
console.log(obj1 == obj2) // false
console.log(obj1 == obj3) // false
Comparing with string and string objects
Quite similar to how objects are compared, if we compare a primitive string with string object (new String()
), object string will be converted to a primitive string and values will be compared.
But if both variables are created using String objects, then they should reference to same object to get true
as an output.
let str1 = "String"
let str2 = `String`
let str3 = String("String")
let str4 = String("String")
let str5 = new String("String")
let str6 = new String("String")
let str7 = str6
console.log(str5 == str6) // false
In this case, every comparison will be computed as true
except one between str5
and str6
. Since both of those are declared as objects and don't reference to same variable, the output will be false
.
For the same reason, if we compare str5
and str7
, the output will be false
.
Strict Equality Operators
There is nothing much that can be added here. Strict equality operators are less confusing... BUT! We need to be extra careful while comparing two objects with strict equality.
let obj1 = { "name": "Adam" }
let obj2 = { "name": "Adam" }
console.log(obj1 === obj2) // false
console.log({} === {}) // false
let obj3 = {}
console.log(obj3 === obj3) // true
The simplest explanation I found about this is from a blog published by Axel Rauschmayer. He says:
"Objects have unique identities and are compared by reference:
Every object you create via an expression such as a constructor or a literal is considered different from every other object; a fact that can be observed via the equality operator (===).
That operator compares objects by reference: two objects are only equal if they have the same identity. It does not matter whether they have the same content or not."
The detailed blog can be found here.
Most of the times in real world scenarios, we end up using strict equality operator just because how simple and straightforward it is.
Key Takeaways ๐
Loose Equality Operators (==)
Loose Equality operator performs type conversion before comparing values.
- when comparing
null
andundefined
, returntrue
. - If
Number
andString
are being compared, try to convert the string into a numeric value. - If both variables are objects, return
true
only if both reference to the same object. - If they have same data type,
Number
: returntrue
only if both variables have same value.String
: returntrue
only if both variables have exact same characters in exact same order.Boolean
: Converttrue
to1
andfalse
to0
and compare likewise.
Strict Equality Operator (===)
Strict equality operator presumes that both variables have same data types and directly compares them.
- When variables have different data types - return
false
. - When both of them are either
null
orundefined
- returntrue
. - Return
false
if any of the variable isNaN
. - When both variables are objects, return
true
only if both refer to same object. - If they have same data types:
Numbers
: Must have numeric values between+0
and-0
.String
: both variables have exact same characters in exact same order.Boolean
: both of them must be eithertrue
orfalse
.
Conclusion โจ
The strict equality operator is best when it comes to real world calculations and software development. 99 percent of the time we should use the same in our code.
And for the 01 percent, ask yourself do you really know what you want and what you are doing. If answers are satisfactory, go on!