Compare Objects with Lodash

Nov 6, 2020

Lodash has an isEqual() function that checks if two values are deeply equal. This function is different from the === operator, which only checks if two objects are the exact same reference:

const obj1 = {
  name: 'Will Riker',
  rank: 'Commander',
  age: 29
};
const obj2 = {
  name: 'Will Riker',
  rank: 'Commander',
  age: 29
};

obj1 === obj1; // true
// `===` only checks if two objects are the same reference, not if the
// the two objects have the exact same keys and values.
obj1 === obj2; // false

// Lodash's `isEqual()` checks if the two objects have the same keys
// and values:
_.isEqual(obj1, obj2); // true

When comparing primitive values, the isEqual() function uses SameValueZero semantics, which means that NaN is considered equal to itself, and +0 is considered equal to -0.

_.isEqual({ x: NaN }, { x: NaN }); // true
_.isEqual({ x: +0 }, { x: -0 }); // true

Built-in Classes

In addition, isEqual() is smart enough to compare arrays, dates, Number instances, and other built-in classes:

const obj1 = {
  date: new Date('2020/06/01'),
  num: new Number(1)
};
const obj2 = {
  date: new Date('2020/06/01'),
  num: 1
};

_.isEqual(obj1, obj2); // true

This makes isEqual() ideal for checking if two POJOs have the same data.

With Classes

The isEqual() function treats two objects as different if they are instances of different classes. For example, even though the two objects in the below example have the same keys and values, they are different because obj2 is an instance of the Character class and obj1 is not.

const obj1 = { name: 'Will Riker', rank: 'Commander' };

class Character {}
const obj2 = new Character();
Object.assign(obj2, { name: 'Will Riker', rank: 'Commander' });

_.isEqual(obj1, obj2); // false

Depending on your use case, this may be an issue. However, in general, you should only use isEqual() for comparing POJOs as opposed to complex classes. In particular, if you want to compare Mongoose documents, you should convert the document to a POJO using toObject() first:

const Character = mongoose.model('Character', Schema({
  _id: false,
  name: String,
  age: Number
}));
const doc = new Character({ name: 'Will Riker', age: 29 });

// false, because `doc` is a document, not a POJO
_.isEqual(doc, { name: 'Will Riker', age: 29 });

// true
_.isEqual(doc.toObject(), { name: 'Will Riker', age: 29 });

More Lodash Tutorials