DEV Community

KevsterDev
KevsterDev

Posted on

How to compare two objects in JavaScript

To begin with, it's essential to understand what an object is in JavaScript.

An object is defined by a set of key-value pairs, where keys are known as "properties" and values can be any JavaScript data type, including other objects or functions. Here's a simple example of a JavaScript object:

const objectExample = {
  name: "John",
  age: 30,
  city: "New York"
}
Enter fullscreen mode Exit fullscreen mode

In JavaScript, objects cannot be directly compared using comparison operators like == or === because these operators check for the equality of values, and objects are actually stored as references in memory, not as actual values. This means that when you compare two objects using these operators, you are comparing their references, not their actual content. You can find a good tutorial on this topic here

For example, let's assume we have two objects:

const object1 = {
  name: "John",
  age: 30,
  city: "New York"
};

const object2 = {
  name: "John",
  age: 30,
  city: "New York"
};
Enter fullscreen mode Exit fullscreen mode

In this scenario, even though these two objects contain the same data, they are stored as separate references in memory. Consequently, the following comparison will return false:

console.log(object1 === object2); // false
Enter fullscreen mode Exit fullscreen mode

So, how do we compare two objects in JavaScript?

how-to-compare-two-objects-in-javascript


The first option is to use JSON.stringify().

This method is an efficient way to compare two objects in JavaScript. This method converts an object into a string representation in JSON format. Since JSON is a standardized format and is represented as a string, the comparison becomes much simpler.

Here is an example of how to use it:

const object1 = {
  name: "John",
  age: 30,
  city: "New York"
};

const object2 = {
  name: "John",
  age: 30,
  city: "New York"
};

const jsonString1 = JSON.stringify(object1);
const jsonString2 = JSON.stringify(object2);

// jsonString1 
// {"name":"John","age":30,"city":"New York"}

// jsonString2
// {"name":"John","age":30,"city":"New York"}

console.log(jsonString1 === jsonString2 ); // true
Enter fullscreen mode Exit fullscreen mode

The order of properties or keys does not matter when using the JSON.stringify() method. JSON is a data format that does not preserve the order of keys in objects. Therefore, even if the order of properties is different between objects, the produced JSON strings will be the same, and their comparison will consider the objects as equal.

However, there are some limitations when using JSON.stringify() to convert objects into JSON strings:

  • Functions If the object contains functions or methods, they will not be included in the JSON string generated by JSON.stringify(). Functions are not serializable in JSON format and will be ignored.
const objectExample = {
  name: "John",
  age: 30,
  city: "New York",
  sayHello: function() {
    console.log("Hello!");
  }
}
Enter fullscreen mode Exit fullscreen mode

If you try to apply JSON.stringify(objectExample) to this object, the sayHello function will be ignored, and the result will only display the serializable properties.

// objectExample
// {"name":"John","age":30,"city":"New York"}
Enter fullscreen mode Exit fullscreen mode
  • Circular References If there are circular references in objects (meaning an object refers to another object, which in turn refers back to the first object), then JSON.stringify will enter an infinite loop and throw an exception. This occurs because JSON format is a linear format, and circular references cannot be directly represented. To learn more about circular references and what they entail, here is a very informative article.

The second approach is to use Shallow equality.

During the shallow equality check of objects, you obtain the list of properties (using Object.keys()) of both objects, and then you check the values of these properties for equality.

function shallowEquality(object1, object2) {
  const keys1 = Object.keys(object1);
  const keys2 = Object.keys(object2);

  if (keys1.length !== keys2.length) {
    return false;
  }

  for (let key of keys1) {
    if (object1[key] !== object2[key]) {
      return false;
    }
  }

  return true;
}
Enter fullscreen mode Exit fullscreen mode

This function compares two objects for shallow equality. It first retrieves the keys of both objects, checks if the number of keys is the same, and then iterates through the keys to compare the values. If all values are equal, the function returns true; otherwise, it returns false.


The third approach is to use Deep equality.

Deep equality shares similarities with shallow equality but introduces a crucial distinction. In the process of comparing objects, when the values under examination are themselves objects, a recursive equality check is executed on these nested objects.

function deepEqual(obj1, obj2) {
  // Basic check for shallow equality

  for (let key in obj1) {
    // Check if the property exists in both objects
    if (obj1.hasOwnProperty(key) !== obj2.hasOwnProperty(key)) {
      return false;
    } 
    // If the property values are objects, initiate recursive check
    else if (typeof obj1[key] === 'object' && typeof obj2[key] === 'object') {
      // Recursive check for embedded objects
      if (!deepEqual(obj1[key], obj2[key])) {
        return false;
      }
    } 
    // Check for equality of non-object property values
    else if (obj1[key] !== obj2[key]) {
      return false;
    }
  }

  // Additional check for exclusive properties of obj2
  for (let key in obj2) {
    // Check if the property exists only in obj2
    if (obj1.hasOwnProperty(key) !== obj2.hasOwnProperty(key)) {
      return false;
    }
  }

  // If all checks pass, the objects are deeply equal
  return true;
}
Enter fullscreen mode Exit fullscreen mode

Recursive Check for Embedded Objects
If, during the basic check, it is determined that the values being compared are themselves objects, a recursive check is initiated. This process repeats for each embedded object, enabling a deep comparison of all levels of objects.

By applying this recursive approach, deep equality thoroughly explores the structure of objects, ensuring that no detail is overlooked in the comparison process.

const object1 = {
  name: "John",
  age: 30,
  adress: {
    city: "New York"
  }
};

const object2 = {
  name: "John",
  age: 30,
  adress: {
    city: "New York"
  }
};

console.log(deepEqual(object1, object2)); // => true
Enter fullscreen mode Exit fullscreen mode

The fourth approach is to use _.isEqual() from Lodash

Lodash is a popular JavaScript utility library that provides a variety of helpful functions, and one of them is _.isEqual(). This function is designed to perform a deep comparison between two values, checking if they are equivalent in a comprehensive manner.

const _ = require('lodash');

const object1 = {
  name: "John",
  age: 30,
  address: {
    city: "New York"
  }
};

const object2 = {
  name: "John",
  age: 30,
  address: {
    city: "New York"
  }
};

if (_.isEqual(object1, object2)) {
  console.log('The objects are deeply equal.');
} else {
  console.log('The objects are not deeply equal.');
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

In conclusion, understanding how to compare objects in JavaScript is crucial due to their unique nature as collections of key-value pairs. Traditional comparison operators like == or === fall short when dealing with objects, as they compare references rather than content.

JSON.stringify() - A Simple Yet Effective Option
One method for object comparison is using JSON.stringify(). By converting objects to JSON strings, the comparison becomes straightforward. However, it has limitations, such as ignoring functions and struggling with circular references.

Shallow Equality - A Surface-Level Check
Shallow equality involves comparing the values of properties at the top level. It uses Object.keys() to retrieve property lists and checks their values for equality. This approach provides a basic comparison but is limited to the object's first layer.

Deep Equality - Uncovering Hidden Depths
Deep equality takes the comparison a step further. When encountering nested objects, it initiates a recursive check, ensuring a thorough examination of all levels. This method provides a comprehensive solution, covering not only the surface but also the inner depths of objects.

Lodash's _.isEqual() - A Trusted Ally
For a robust and widely used solution, Lodash's _.isEqual() comes into play. This utility library function performs a deep comparison, offering a reliable and efficient method to ascertain the equivalence of two objects.

In choosing the right method, consider the complexity of your objects and the depth of the comparison needed. Each approach has its strengths and limitations, so selecting the most suitable one depends on the specific requirements of your JavaScript application.

Top comments (0)