Skip to content

Instantly share code, notes, and snippets.

@attaboy
Last active June 8, 2016 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save attaboy/4208bfb6feaca0032dba656736b89a34 to your computer and use it in GitHub Desktop.
Save attaboy/4208bfb6feaca0032dba656736b89a34 to your computer and use it in GitHub Desktop.
Object equality
/*
deepEquals tests two objects and returns true if:
- both objects are === identical
- both objects are NaN
- both objects are arrays, and at each index, the values are deepEquals (recursively)
- both objects have the same prototype, the same keys, and at each key, the values are deepEquals (recursively)
- a function reference is compared to another reference to the same function
deepEquals returns false if:
- two objects have the same keys and values, but were created with different constructors
- two arrays have the same values in a different order
- a function is compared with another function, even if they have identical declarations
Examples:
deepEquals("foo", "foo") // true
deepEquals("foo", "bar") // false
deepEquals(Infinity, Infinity) // true
deepEquals([], []) // true
deepEquals({}, {}) // true
deepEquals([0, 1, 2], [0, 1, 2]) // true
deepEquals([0, 1, 2], [2, 1, 0]) // false
deepEquals({ a: 'b', 'b': a }, { a: 'b', b: 'a' }) // true
deepEquals({ a: 'b', 'b': a }, { b: 'a', a: 'b' }) // true
deepEquals({ a: { b: { c: 'd' }}}, { a: { b: { c: 'd' }) // true
deepEquals([0, { a: 'b', b: 'a' }], [0, { b: 'a', a: 'b' }) // true
var f = function() { return; };
var g = f;
deepEquals(f, g) // true
deepEquals(f, function() { return; }) // false
var Car = function() {
this.make = 'Ford';
return this;
}
var Truck = function() {
this.make = 'Ford';
return this;
}
var car = new Car();
var truck = new Truck();
deepEquals(car, truck) // false
*/
function deepEquals(thing1, thing2) {
if (thing1 === thing2) {
return true;
} else if (Number.isNaN(thing1) && Number.isNaN(thing2)) {
return true;
} else if (Array.isArray(thing1) && Array.isArray(thing2)) {
return arraysEqual(thing1, thing2);
} else if (typeof(thing1) === 'object' && typeof(thing2) === 'object') {
return objectsEqual(thing1, thing2);
} else {
return false;
}
}
function arraysEqual(array1, array2) {
if (array1.length !== array2.length) {
return false;
} else {
return array1.every(function(item, index) {
return deepEquals(array1[index], array2[index]);
});
}
}
function objectsEqual(obj1, obj2) {
if (obj1.constructor !== obj2.constructor) {
return false;
}
var obj1Keys = Object.keys(obj1);
var obj2Keys = Object.keys(obj2);
if (!arraysEqual(obj1Keys.sort(), obj2Keys.sort())) {
return false;
}
return obj1Keys.every(function(key) {
return deepEquals(obj1[key], obj2[key]);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment