# Deeply Compare 2 Objects in JavaScript with Recursive Function

On this article, we are going to examine two objects deeply. The objects that we are going to examine can’t solely have strings, numbers, and boolean as properties but additionally nested objects.

### Why it is slightly bit robust to check two objects

In JavaScript, objects are saved by reference. Which means one object is strictly equal to a different provided that they each level to the identical object in reminiscence.

`This GIF is collected from panjee.com and modified afterward.`

``````const obj_1 = { rating: 12 }
const obj_2 = obj_1
const obj_3 = { rating: 12 }

obj_1 === obj_2; // true, similar reference
obj_1 === obj_3 // false, completely different reference however similar keys and values
``````

### Let’s Evaluate Two Objects

We have to test a number of issues to check two objects. So, we are going to break down the comparability course of into a number of steps:

Step 1

Let’s first create a perform (`deepComparison`) that has two parameters (`first`, `second`).

``````perform deepComparison (first, second) {

...

}
``````

If we go two objects because the arguments of this perform, this perform will return a boolean worth after evaluating them.

Step 2

Our actual work is starting from this step. On this step, we are going to test if the categories and values of the 2 arguments are the identical. If they’re the identical, we are going to return `true`. In any other case, we are going to transfer ahead to the following step.

``````perform deepComparison (first, second) {

/* Utilizing the strict equality operator (===) */
if(first === second) return true

}

``````

Step 3

On this step, we are going to test whether or not any of the arguments is `null`. If any argument is `null`, we are going to return `false`. But when none of them are null, we are going to transfer ahead to the following step.

``````perform deepComparison (first, second)  second === null) return false

``````

Step 4

Now, we are going to make it possible for each arguments are objects. If any of the arguments is just not an object, we are going to return `false`.

``````perform deepComparison (first, second)  typeof second !== 'object') return false

``````

Step 5

Within the final step, we have now made positive that each arguments are objects. On this step, we are going to test whether or not each objects have the identical variety of properties or not. If they do not have the identical variety of properties, we are going to return `false`.

``````perform deepComparison (first, second) {

...

/* Utilizing Object.keys() technique to return the record of the objects’ properties*/
let first_keys = Object.keys(first)

let second_keys = Object.keys(second)

/* Utilizing array.size() technique to depend the variety of complete property */
if(first_keys.size !== second_keys.size) return false

}

``````

Step 6

Within the final step, we made positive that each objects have the identical variety of properties. Now, we have to make it possible for the properties’ names of each objects are the identical. If they aren’t the identical, we are going to return `false`. But when they’re the identical, we are going to transfer ahead to the following step.

``````perform deepComparison (first, second) {

...

/* Iterating by means of all of the properties of the primary object with for of technique */
for(let key of first_keys) {

/* Ensuring that each property within the first object additionally exists within the second object */
if (!second_keys.consists of(key)) return false

}

}

``````

Notice:

Right here, we’re utilizing the `for..of` technique for iteration as a result of `for..of` can’t solely iterate over an object but additionally an array. As we could needn’t solely to iterate over the item but additionally over nested array inside the item, so we’re utilizing `for..of`

Step 7

Within the final step, we made positive that the property names of each objects are the identical. Now, we are going to test whether or not the property values of each objects are the identical or not.

This step is slightly bit tough as a result of:

• The property values can’t solely be strings, numbers, or boolean but additionally nested objects.
• Simply checking with strict equality operator (===) can be sufficient if the values had been string or quantity or boolean however it would not be sufficient for an object as a result of the nested object may have its personal properties.
• Let’s suppose that the nested object has one other object inside it as a property! What is going to we do? Will we test one after the other!

Resolution:

• Within the step 1, we created this `deepComparison` perform, and this perform not solely checks the strict equality operator (===), but additionally it checks null or not, object or not, properties of objects are similar or not. So, really, we want a perform like this `deepComparison` to test any nested object’s properties.
• Fortuitously, we needn’t create any new perform as a result of there’s a time period referred to as the recursive perform. A recursive perform is a perform that calls itself throughout its execution. So, really, we will use this `deepComparision` perform as a recursive perform.

Now, let’s use this `deepComparision` perform to test whether or not the property values of each objects are the identical or not. If they aren’t the identical, we are going to return `false`.

``````perform deepComparison (first, second) {

...

for(let key of first_keys) {

...

/* Utilizing the deepComparison perform recursively and passing the values of every property into it to test if they're equal. */

if (deepComparison(first[key], second[key]) === false) return false

}

``````

Notice

Because the `deepComparision` is inside a loop. So, it’ll proceed to execute itself until it finishes checking all of the nested objects.

Step 8

If we’re on this `step 8`, meaning no different step’s situation matched. As we have now checked virtually all potential methods through which the objects usually are not the identical and none of these situations matched, so now we will absolutely say that the objects are the identical. So, we are going to merely return `true` on this step.

``````perform deepComparison (first, second) {

...

for(let key of first_keys) {

...

}

return true

}

``````

### Full Code

``````perform deepComparison (first, second) {

/* Checking if the categories and values of the 2 arguments are the identical. */
if(first === second) return true

/* Checking if any arguments are null */
if(first === null || second === null) return false

/* Checking if any argument is none object */
if(typeof first !== 'object'  || typeof second !== 'object') return false

/* Utilizing Object.keys() technique to return the record of the objects’ properties */
let first_keys = Object.keys(first)

let second_keys = Object.keys(second)

/* Checking if the objects' size are similar*/
if(first_keys.size !== second_keys.size) return false

/* Iterating by means of all of the properties of the primary object with the for of technique*/
for(let key of first_keys) {

/* Ensuring that each property within the first object additionally exists in second object. */
if (!second_keys.consists of(key)) return false

/* Utilizing the deepComparison perform recursively (calling itself) and passing the values of every property into it to test if they're equal. */
if (deepComparison(first[key], second[key]) === false) return false

}

/* if no case matches, returning true */
return true

}

``````

Let’s take a look at

``````

let obj1 = {
a: 1,
b: 2,
c: { foo: 1, bar: 2},
d: { baz: 1, bat: 2, arr: [2,3] }
}

let obj2 = {
a: 1,
b: 2,
c: { foo: 1, bar: 2},
d: { baz: 1, bat: 2, arr: [2,3] }
}

let obj3 = {
identify: "Rahim",
teacher: true,
favoriteHobbies: ["Playing Cricket", "Tennis", "Coding"],
citiesLivedIn: ["Rajshahi", "Rangpur", "Joypurhat"]
}
}

let obj4 = {
identify: "Rahim",
teacher: true,
favoriteHobbies: ["Playing Cricket", "Tennis", "Coding"],
citiesLivedIn: ["Rajshahi", "Rangpur", "Joypurhat"]
}
}

``````

``````
console.log(deepComparison(obj1, obj2)) //true
console.log(deepComparison(obj1, obj3)) //false
console.log(deepComparison(obj2, obj3)) // false
console.log(deepComparison(obj3, obj4)) //true

``````

That is it. 😃 Thanks for studying. 🎉 If you happen to discover any typos or errors, or if you wish to add one thing, please write it down within the remark part.