Understanding “==” (Abstract Equality) and “===” (Strict Equality) in JavaScript

Himanshu KumarHimanshu Kumar
6 min read

A lot of people including me had a misconception that in JavaScript “==” doesn’t check type and “===” does, but sometimes we have to unlearn some things.

So before understanding these two equalities we have to understand Coercion.

What is Coercion

Coercion in JavaScript is the automatic conversion of a value from one data type to another data type.

JavaScript has two types of coercion

  • Explicit

  • Implicit

Explicit coercion happens when the programmer explicitly converts a value from one type to another, using functions such as Number(), String(), and Boolean().

Implicit coercion, on the other hand, happens automatically when JavaScript converts a value to another type behind the scenes.

Examples:-

Implicit Coercion uses some set of operations that are present in the ECMAScript but they are not available for usage in the ECMAScript. ie., as developers we cannot use these operations directly. ECMAScript defines several abstract functions including Type, ToPrimitive, ToString, ToNumber, and ToObject for defining the behavior of language constructs and operations.

For the time being let's understand what are ToPrimitive and ToNumber.

ToPrimitive is a built-in abstract operation in JavaScript that converts a value to a primitive value.

Here's how ToPrimitive works:

  1. If the input value is already a primitive value, return it as-is.

  2. Otherwise, if the input value has a valueOf method that returns a primitive value, call that method and return the result.

  3. Otherwise, if the input value has a toString method that returns a primitive value, call that method and return the result.

  4. Otherwise, throw a TypeError.

In this example, obj is an object that has both a valueOf method that returns the number 42, and a toString method that returns the string "foo". When we use the + operator to add obj and 5, the ToPrimitive operation is called on obj, with a default hint of "number". The valueOf method is called first and returns the primitive value 42, which is then added to the number 5, resulting in the number 47.

ToNumber is a built-in abstract operation in JavaScript that converts a value to a number. ToNumber takes an input value as its argument and returns a numeric value based on the type and value of the input.

Here's how ToNumber works:-

  1. If the input value is already a number, return it as-is.

  2. If the input value is a string, attempt to convert it to a number using the following rules:

    • If the string begins with a valid numeric literal (e.g. "123", "-456", "3.14"), parse it into a corresponding number value.

    • If the string does not begin with a valid numeric literal, or if it contains characters that cannot be parsed as part of a number (e.g. "foo", "123abc"), return NaN.

  3. If the input value is a boolean, return 1 if the value is true, and 0 if the value is false.

  4. If the input value is null, return 0.

  5. If the input value is undefined, return NaN.

  6. If the input value is an object, attempt to call its valueOf method. If the result of the method call is a primitive value, return the result after performing ToNumber on it. Otherwise, call the object's toString method and return the result after performing ToNumber on it.

  7. Otherwise, throw a TypeError.

I know it's overwhelming but bear with me 😁

So these are the set of rules which ECMAScript follows for Abstract Equality Comparison.

As you can see from point number 1 "==" actually checks the type of the numbers which it is comparing, if it is the same then it returns the result after following the rules which Strict Equality Comparison follows.

Now if we follow point number 2 and 3

we got to know why "null == undefined" is true.

Let's understand point number 4 and 5

Here if any of the two numbers is a string then ECMAScript will prefer a number comparison and converts the string into a number and then do the comparison.

Example:-

const a = 10;

const b = "10";

const isEqual = a == b;

Here isEqual will result in true, as the string "10" is implicitly coerced to the number 10.

Point number 6 and 7 says that

If after doing the above operations, any of the two numbers become boolean or if we are directly doing abstract equality in boolean then it will follow these steps.

Note:- 'true' is converted to '1 ' and 'false' is converted to '0' during coercion.

Example:-

true == 1; // returns true

false == 0; // returns true

true == "1"; // returns true

false == ""; // returns true

true == "true"; // returns false

false == "false"; // returns false

At last, let's understand points 8 and 9

It tells us that if any of the two is an object and the others are string, number or symbol then it will convert the object to a primitive value before doing abstract equality.

Now we understood the rules of Abstract Equality let's see the rules which Strict Equality comparison follows

So in Strict Equality, if the type of x is different from the type of y it simply returns false, no coercion is going to happen.

Now things get interesting from point2

we can see if x or y any of them is NaN then it simply returns false as a result we got the answer to why NaN is not equal to NaN.

and same for the why +0 is equal to -0

For the 3rd rule please read below:-

here for objects, we have to take some extra note

For Example:-

here we can see that obj1 === obj2 is giving false although the key-value pair is the same, this is because they are 2 different objects pointing/present in a different memory location, so if we compare the same memory objects like obj1 === obj1 as they are present in the same memory location it will result in true.

Note:*- We often say JavaScript is weird if we don't understand something about it, due to this it is one of the most hated languages but we also have to understand it is the most loved language also (Quoted Akshay Saini😉). If we know the rules of the language on which it is based then we understand the language better.*

Peace☮

Credits: - I have referred to the official docs of ECMAScript for the rules which you are seeing in the blog.

Special Thanks! to Sanket Singh by following his lessons I can go this deep into the world of Javascript.

0
Subscribe to my newsletter

Read articles from Himanshu Kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Himanshu Kumar
Himanshu Kumar

Front-End Developer, passionate about creating web apps and websites. React, JavaScript, HTML, CSS, AEM