Skip to content
GreenSnippets

Deep equality check

Compare two values structurally, including nested objects, arrays, Dates, Maps and Sets.

JavaScript
function deepEqual(a, b) {
  if (Object.is(a, b)) return true;
  if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
  if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false;
  if (a instanceof Date) return a.getTime() === b.getTime();
  if (a instanceof Map || a instanceof Set) {
    if (a.size !== b.size) return false;
    const left = [...a];
    const right = [...b];
    return left.every((entry, i) => deepEqual(entry, right[i]));
  }
  const keysA = Object.keys(a);
  if (keysA.length !== Object.keys(b).length) return false;
  return keysA.every((key) => Object.hasOwn(b, key) && deepEqual(a[key], b[key]));
}

Example / expected output

Output
deepEqual({ a: [1, { b: 2 }] }, { a: [1, { b: 2 }] }) // true

How it works

=== compares references. This recursive check treats NaN as equal to itself, compares Dates by time, and Maps and Sets by their entries in order. It does not handle circular structures; on the server, isDeepStrictEqual from node:util covers those.