merging two objects in JavaScript

Comparing Two Objects in JavaScript: A Step-by-Step Guide

Comparison of Objects in JavaScript can be a tricky task. Even though they may seem identical, that’s not always the case. 

This article discusses equality comparison, JSON.stringify, and deep equality comparison, along with the nuances of how this algorithm works in JavaScript.

Equality Comparison

Let’s consider the following scenario: you have two objects, ‘a’ and ‘b’, with identical properties and values.

const a = { name: 'John', age: 26 }; const b = { name: 'John', age: 26 }; a === b; // false

Surprisingly, JavaScript doesn’t consider them equal when using loose or strict equality operators (== or ===). The reason is that JavaScript compares objects by reference, not by their content. Primitive values, on the other hand, are compared based on their actual values.

JSON.stringify

To address this issue, many developers turn to the JSON.stringify() method. This method converts objects into serialized strings, making them comparable.

const equals = (a, b) => JSON.stringify(a) === JSON.stringify(b); const a = { name: 'John', age: 26 }; const b = { name: 'John', age: 26 }; equals(a, b); // true const c = { name: 'John' }; const d = { name: 'John', age: undefined }; equals(c, d); // true, should be false

Although JSON.stringify() can be helpful, it has its drawbacks. It may incorrectly assess similar but not identical values as identical due to their shared serialized string.

Deep Equality Comparison

Solving the complexity of comparison led to the creation of helper functions for shallow and deep comparison. These functions use recursion to thoroughly compare two objects, considering various scenarios, including empty values, special types, and nested objects.

const equals = (a, b) => { if (a === b) return true; if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime(); if (!a || !b || (typeof a !== 'object' && typeof b !== 'object')) return a === b; if (a.prototype !== b.prototype) return false; const keys = Object.keys(a); if (keys.length !== Object.keys(b).length) return false; return keys.every(k => equals(a[k], b[k])); }; const a = { name: 'John', age: 26 }; const b = { name: 'John', age: 26 }; equals(a, b); // true const c = { name: 'John' }; const d = { name: 'John', age: undefined }; equals(c, d); // false

This helper function addresses a wide range of comparison tasks, providing a reliable check for objects.

How to Assert 2 Objects Are Equal in JavaScript?

In JavaScript, asserting that two objects are equal can be somewhat challenging because they are, by default, compared by reference. To assert that these elements have the same properties and values, you can use various techniques:

Using a Testing Library: JavaScript testing libraries like Jest, Mocha, or Chai offer assertion functions that simplify object comparison. For example, in Chai:

const expect = require('chai').expect; const object1 = { name: 'John', age: 30 }; const object2 = { name: 'John', age: 30 }; expect(object1).to.deep.equal(object2);

Using a Custom Function: To perform a deep comparison, you can write a custom function. Here’s an example of such a function:

function deepEqual(obj1, obj2) { if (obj1 === obj2) return true; if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false; const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) return false; for (const key of keys1) { if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) return false; } return true; } const object1 = { name: 'John', age: 30 }; const object2 = { name: 'John', age: 30 }; if (deepEqual(object1, object2)) { console.log('Objects are equal.'); } else { console.log('Objects are not equal.'); }

Using Lodash: The popular JavaScript utility library Lodash provides the _.isEqual function for deep equality checking:

const _ = require('lodash'); const object1 = { name: 'John', age: 30 }; const object2 = { name: 'John', age: 30 }; if (_.isEqual(object1, object2)) { console.log('Objects are equal.'); } else { console.log('Objects are not equal.'); }
Using JSON.stringify: You can also use JSON.stringify for a simple equality check:


const object1 = { name: 'John', age: 30 }; const object2 = { name: 'John', age: 30 }; if (JSON.stringify(object1) === JSON.stringify(object2)) { console.log('Objects are equal.'); } else { console.log('Objects are not equal.'); }

These techniques offer different levels of granularity in object comparison, depending on your specific needs.

Remember that each of these methods has its limitations and peculiarities, so choose the one that best suits your specific use case and requirements. For more complex object structures, it’s often preferable to use a custom deep equality function or a library like Lodash.

Conclusion

In JavaScript, comparing objects for equality is a task that demands attention to detail and an understanding of the language’s nuances. In this article, we explored various methods for asserting their equality and emphasized the importance of choosing the right approach depending on the specific use case.

When it comes to object equality, keep these key points in mind:

  • Reference vs. Value: JavaScript compares objects by reference, not by value. Even with identical properties and values, they won’t be considered equal until you explicitly check their content;
  • Testing Libraries: Testing libraries like Jest, Mocha, and Chai offer built-in functions for deep object equality checks. These libraries simplify the assertion process and are an excellent choice when writing tests;
  • Custom Equality Function: For greater control over the comparison process, consider implementing a custom deep equality function. This approach allows you to fine-tune the comparison logic according to specific needs;
  • Lodash: If you prefer using established utility libraries, Lodash’s _.isEqual function provides a reliable way to perform deep comparisons;
  • JSON Serialization: Serializing objects into JSON strings and comparing them can be a quick solution in some cases, but be cautious as it may lead to incorrect handling of functions or undefined values.

The choice of method depends on the project requirements and the complexity of the objects you need to compare. Understanding the nuances of object equality in JavaScript will help you write more robust and reliable code. Whether you’re building web applications, writing tests, or simply verifying data consistency, mastering object comparison is an essential skill in your JavaScript developer toolbox.

The difference between for…in, for…of and forEach?

Comparison of Objects in JavaScript can be a tricky task. Even though they may seem identical, that’s not always the case.  This article discusses equality comparison, JSON.stringify, and deep equality comparison, along with the nuances of how this algorithm works in JavaScript. Equality Comparison Let’s consider the following scenario: you have two objects, ‘a’ and …

The Nuances between .then() and .finally() in JS Promises

Comparison of Objects in JavaScript can be a tricky task. Even though they may seem identical, that’s not always the case.  This article discusses equality comparison, JSON.stringify, and deep equality comparison, along with the nuances of how this algorithm works in JavaScript. Equality Comparison Let’s consider the following scenario: you have two objects, ‘a’ and …