Last active
June 8, 2016 20:40
-
-
Save attaboy/4208bfb6feaca0032dba656736b89a34 to your computer and use it in GitHub Desktop.
Object equality
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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