Languages
[Edit]
EN

JavaScript - deep compare of two objects

6 points
Created by:
AnnLen
1777

In this article we are going to look how to compare two objects in JavaScript. By default JavaScript provides == and === operators. But thay are not enought to compare complex objects because they compares only references for them. To solve this problem it is necessary to attach external library or write custom function.

Below simple custom implementation for equals method is presented.

1. Deep compare objects method example

Presented solution in this section uses recursion to compare properties.

// ONLINE-RUNNER:browser;

function equals(a, b) {
  if (a === b) {
    return true;
  }

  if ((a instanceof Object) && (b instanceof Object)) {
    if (a.constructor !== b.constructor) {
      return false;
    }

    for (const key in a) {
      if (a.hasOwnProperty(key)) {
        if (!b.hasOwnProperty(key) || !equals(a[key], b[key])) {
          return false;
        }
      }
    }

    for (const key in b) {
      if (b.hasOwnProperty(key) && !a.hasOwnProperty(key)) {
        return false;
      }
    }

    return true;
  }

  return false;
}

// Usage example:

var object1 = {
	name: 'John',
  	items: [1, 2, '3', {name: 'Item'}]
};

var object2 = {
	name: 'John',
  	items: [1, 2, '3', {name: 'Item 2'}]
};

var array1 = [1, 2, 3];
var array2 = [1, 2, '3'];

console.log( equals(        1,      1  ) ); // true
console.log( equals(    'abc',  'abc'  ) ); // true
   
console.log( equals(    null,    null  ) ); // true
console.log( equals(    true,   false  ) ); // false
console.log( equals(     123,   '123'  ) ); // false

console.log( equals( object1, object1  ) ); // true
console.log( equals( object1, object2  ) ); // false
console.log( equals(  array1,  array1  ) ); // true
console.log( equals(  array1,  array2  ) ); // false

2. Deep compare objects method with printing difference example

In this section extended equals method that logs difference between objects is presented.

// ONLINE-RUNNER:browser;

function compare(a, b) {
  var logs = [];

  function log(log, path) {
    if (path) {
      logs.push(log + ' (path: ' + path + ').');
    } else {
      logs.push(log + '.');
    }
  }

  function analyse(a, b, path) {
    if (a === b) {
      return;
    }

    if ((a instanceof Object) && (b instanceof Object)) {
      if (a.constructor !== b.constructor) {
        log('Entities do not have same constructors', path);
        return;
      }

      for (const key in a) {
        if (a.hasOwnProperty(key)) {
          if (!b.hasOwnProperty(key)) {
            log('Property "' + key + '" does not exist in first entity', path);
            continue;
          }
          analyse(a[key], b[key], path ? path + ' -> ' + key: key) ;
        }
      }

      for (const key in b) {
        if (b.hasOwnProperty(key) && !a.hasOwnProperty(key)) {
          log('Property "' + key + '" does not exist in second entity', path);
        }
      }
    } else {
      log('Entities are not equal', path);
    }
  }

  analyse(a, b, '');

  return logs;
}

// Usage example:

var object1 = {
  name: 'John',
  items: [1, 2, '3', {name: 'Item', z: [4]}]
};

var object2 = {
  name: 'John',
  items: ['1', 2, 3, {name: 'Item 2', x: 3}]
};

var logs = compare(object1,  object2);

if (logs.length == 0) {
  console.log('Objects are equal.');
} else {
  console.log('Objects differ in:');

  for (var  i = 0; i < logs.length; ++i) {
    console.log(' ' + logs[i]);
  }  
}

 

Hey 👋
Would you like to know what we do?
  • Dirask is a friendly IT community for learners, professionals and hobbyists to share their knowledge and help each other in extraordinary easy way.
  • We welcome everyone,
    no matter what the experience,
    no matter how basic the question is,
    this community will help you.