DEV Community

Alok Kumar
Alok Kumar

Posted on

4 2

JS Equality in-depth

Hey All πŸ‘‹

We are often asked what's the difference between == and ===,
And the most common answer we have is == does loose comparison or it ignores types while comparison and === does strict comparison or it doesn't ignore types while comparison. But there is more to that and in this article we will discuss in detail about Equality operators in JavaScript.


Double & Triple Equals

Let's talk about both of them one-by-one with their algorithms :-

Strict Equality Comparison ( === )

The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:

Strict Equality Comparison

1) If we are comparing two values and both of them have different types, it'll not do any comparison and simply returns false.

Example :-

1 === "1" // false
1 === true // false
1 === undefined // false
1 === [1] // false
Enter fullscreen mode Exit fullscreen mode

2) If typeof(x) is Number then :-

a & b } If any of x or y is NaN then it returns false.

Example :-

1 === NaN // false
NaN === 1 // false
Enter fullscreen mode Exit fullscreen mode

c } If x and y has the same number value then it returns true.

Example :-

123 === 123 // true
12.3 === 12.3 // true
0.2 === 0.2 // true
Enter fullscreen mode Exit fullscreen mode

d & e } If x is +0 and y is -0 or vice-versa it returns true.

Example :-

+0 === -0 // true
-0 === +0 // true
Enter fullscreen mode Exit fullscreen mode

f } else returns false.

Example :-

1 === +Infinity // false
1 === -Infinity // false
Enter fullscreen mode Exit fullscreen mode

3) When neither x nor y are number values then comparison is performed as follows:

Same Value Non Number

1 & 2 } Conditions - typeof(x) is not Number and typeof(x) is same as typeof(y).

3 & 4 } If typeof(x) is Undefined or Null then it returns true.

null === null // true
undefined === undefined // true
null === undefined // false as typeof(null) is not same as typeof(undefined)
Enter fullscreen mode Exit fullscreen mode

5 a} If typeof(x) is String also x and y are exactly the same sequence of code units then it returns true otherwise false.

**Example - *

"alok" === "alok" // true
"alok12" === "alok12" // true
"alok" === "Alok" // false
Enter fullscreen mode Exit fullscreen mode

6 a} If typeof(x) is Boolean and if both x and y are true or both are false it returns true otherwise returns false.

Example -

true === true // true
false === false // true
true === false // false
Enter fullscreen mode Exit fullscreen mode

7 a} If typeof(x) is Symbol and if both x and y are same symbol value it returns true otherwise it returns false.

Example -

let a = Symbol('hey');
let b = Symbol('hey');
let c = a;

a === b // false
a === c // true
a.description === b.description // true
Enter fullscreen mode Exit fullscreen mode

Here we have created two symbols a and b, though they look the same but have different values, and comparing them returns false. a and c point to the same symbol value thus comparing them returns true. Also, the values of descriptions of a and b are the same thus comparing them returns true.

8 } If x and y are the same object value, then it returns true. Otherwise, it returns false..

Example -

let a = {a:1};
let b = {a:1};
let c = a;

a === b // false
a === c // true
a.a === b.a // true
Enter fullscreen mode Exit fullscreen mode

Here we have created two objects a and b, and similar to symbols, though they look the same but have different values, and comparing them returns false. a and c point to the same object value thus comparing them returns true. Also, the values of property (a) of object a and b are the same thus comparing them returns true.

Abstract Equality Comparison ( == )

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

Abstract Equality Comparison

1) If x and y both are of same type then it'll do the === operation on them.

2 & 3) If x is null and y is undefined or vice-versa it returns true.

Example -

null == undefined // true
undefined == null // true
Enter fullscreen mode Exit fullscreen mode

4 & 5) If one of the values is number and the other is string then == prefer numeric comparison i.e. coerce string to number.

Example -

Number("2") // 2
Number("A") // NaN

2 == "2" // 2 == 2 -> true
"4" == 4 // true
2 == "3" // 2 == 3 -> false
1 == "A" // 1 == NaN -> false
Enter fullscreen mode Exit fullscreen mode

6 & 7) Similarly if one of the values is boolean then == prefer numeric comparison i.e. coerce boolean to number.

Example -

Number(true) // 1
Number(false) // 0

1 == true // 1 == 1 -> true
0 == false // 0 == 0 -> true
4 == true // false
"A" == true // "A" == 1 -> NaN == 1 -> false
Enter fullscreen mode Exit fullscreen mode

8 & 9) If one of the values is object then == tries to convert the object to it's primitive form.

You can read more about ToPrimitive here, but to simply put it - ToPrimitive() takes two params, an object value and a hint (in case of == the hint is "default") and tries to convert the object to primitive, based on the hint.

If the hint is "default" it takes the hint based on the other value.

If the hint is "number" it tries to convert the object to number using "valueOf" then "toString".

If the hint is "string" it tries to convert the object to string using "toString" then "valueOf".

Example -

let a = "alok";
let b = ["alok"];
b.toString(); // 'alok' i.e. primitive

a == b; // "alok" == "alok" -> true

let c = ["alok","1"];
c.toString(); // 'alok,1' i.e. primitive

a == c; // "alok" == 'alok,1' -> false
Enter fullscreen mode Exit fullscreen mode

Here when comparing a string and object the hint is "string" and it tries converting the object (["alok"]) to primitive and as the hint is "string" it first tries "toString" and gets "alok" which is a primitive and then the comparison is done.

Example -

let a = "alok";
let c = ["alok","1"];

c.toString(); // 'alok,1' i.e. primitive

a == c; // "alok" == 'alok,1' -> false
Enter fullscreen mode Exit fullscreen mode

Example -

let a = 1;
let b = ["1"];

b.valueOf(); // [ '1' ] i.e. not primitive
b.toString() // '1' i.e. primitive

a == b; // 1 == "1" -> 1 == 1 -> true
Enter fullscreen mode Exit fullscreen mode

Here when comparing a number and object the hint is "number" and it tries converting the object (["1"]) to primitive and as the hint is "number" it first tries "valueOf" and gets [ '1' ] which is not primitive thus it tries "toString" and gets "1" which is a primitive and then the comparison is done.

10 ) else return false


Wrapping Up

We just saw that == and === is not just simply loose comparison and strict comparison rather == allows coercion and === doesn't. Knowing these details will surely help you to write better code.

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay