Languages
[Edit]
EN

JavaScript - deep compare of two objects

6 points
Created by:
AnnLen
9150

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]);
  }  
}

 

Native Advertising
50 000 ad impressions - 449$
🚀
Get your tech brand or product in front of software developers.
For more information contact us:
Red dot
Dirask - friendly IT community for everyone.

❤️💻 🙂

Join