JavaScript Basics: Double Equals (==) and Triple Equals (===)

JavaScript Basics: Double Equals (==) and Triple Equals (===)

ยท

5 min read

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 and undefined, return true.
  • If Number and String 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: return true only if both variables have same value.
    • String: return true only if both variables have exact same characters in exact same order.
    • Boolean: Convert true to 1 and false to 0 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 or undefined - return true.
  • Return false if any of the variable is NaN.
  • 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 either true or false.

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!

ย