JavaScript Basics: Double Equals (==) and Triple Equals (===)
Tags: javascript, webdev, beginners, programming
Published: 2021-12-22 05:16:21

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:

```js
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.

```js
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.

```js
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. 

```js
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](https://twitter.com/rauschma). 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](https://2ality.com/2011/03/javascript-values-not-everything-is.html).

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!