/** * @param {any} o1 * @param {any} o2 * @return {boolean} */ var areDeeplyEqual = function(o1, o2) { // passes strict equality if (o1 === o2) { return true; } // one is ‹null› if (o1 === null || o2 === null) { return false; } // different string representations if (String(o1) != String(o2)) { return false; } // if it's not an object we can decide with strict equality if (typeof o1 !== 'object') { return o1 === o2; } if (Array.isArray(o1)) { return ( o1.length === o2.length && Array.from(o1.keys()).every(i => areDeeplyEqual(o1[i], o2[i])) ); } return ( Object.keys(o1).length === Object.keys(o2).length && Object.keys(o1).every(key => areDeeplyEqual(o1[key], o2[key])) ); };