Compare objects with JavaScript
With JavaScript, comparing objects is not as easey as one might think. Given the example below you might expect this to work:
let object1 = {name:"Billy Bob"};
let object2 = {name:"Billy Bob"};
let equal = object1 == object2; // false
But it does not :( ... So what is the best way to compare objects in JavaScript?
Not JSON.stringify()
I have seen alot of examples of using JSON.stringify()
to compare objects. This will turn the object into its string equivalant then do a regular string compare.
JSON.stringify(object1) === JSON.stringify(object2) // true
At first glance you might think this is enough, but because it stringifies the object as is, the property order is very important:
let object1 = {name:"Billy Bob",age:12};
let object2 = {age:12,name:"Billy Bob"};
let equals = JSON.stringify(object1) === JSON.stringify(object2); // false
I would highly recommend staying away from this one. It is unlikely you will be dealing with objects with consistent property placement.
Deep compare
The most sure-fire way to check if objects are equal is by comparing each individual property.
function deepIsEqual(first, second) {
// If first and second are the same type and have the same value
// Useful if strings or other primitive types are compared
if( first === second ) return true;
// Try a quick compare by seeing if the length of properties are the same
let firstProps = Object.getOwnPropertyNames(first);
let secondProps = Object.getOwnPropertyNames(second);
// Check different amount of properties
if( firstProps.length != secondProps.length ) return false;
// Go through properties of first object
for(var i=0; i<firstProps.length; i++) {
let prop = firstProps[i];
// Check the type of property to perform different comparisons
switch( typeof( first[prop] ) ) {
// If it is an object, decend for deep compare
case 'object':
if( !deepIsEqual(first[prop], second[prop]) ) return false;
break;
case 'number':
// with JavaScript NaN != NaN so we need a special check
if(isNaN(first[prop]) && isNaN(second[prop])) break;
default:
if( first[prop] != second[prop] ) return false;
}
}
return true;
};
With deepIsEqual
we are going to quickly perform some checks on the object to see if:
- They are straight up indentical
- They have identical property lengths
This will speed up the initial check before decending into the property comparison:
- Check the type of property
- If an
object
, calldeepIsEqual
on the property (performing the deep compare) - If a
number
we need to check if both values areNaN
asNaN
is not equal toNaN
in JavaScript
- If an
- Compare the properties to see if they are equal
There you have it! A simple way to compare two objects.
Existing packages for comparing JavaScript objects
Now that you understand the logic behind comparing objects you should also know what is available already to use:
- Lodash - a JavaScript utility library has a
_.isEqual()
method for deeply comparing two objects - is-equal - an npm package for checking equality.
- fast-equals - another npm package that adds a few edge cases to check against.