Skip to content
JavaScript utilities · Senior · about 20 minutes

Deep equal

Implement deepEqual(a, b). Primitives compare with Object.is, so NaN equals NaN (shown as null in the test input). Arrays and plain objects are equal when they have the same own keys with deeply equal values; key order does not matter. Two Dates are equal when their times are equal. An array never equals a plain object.

Start from

function deepEqual(a, b) {
  // Return true when a and b have the same shape and values.
}

Hints

Each hint gives away a little more. Open one only when you need it.

  1. Hint 1

    Start with Object.is. Then both must be non-null objects, or they are different.

  2. Hint 2

    Compare the number of keys, then check each key of a exists on b and its value is deeply equal.

  3. Hint 3

    Dates and the array-against-object case need their own lines before the key loop.

Solution

From here on the page gives the method away. If you are still solving, go back to the hints.

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 (a instanceof Date || b instanceof Date)
    return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();
  if (Array.isArray(a) !== Array.isArray(b)) return false;
  const keys = Object.keys(a);
  if (keys.length !== Object.keys(b).length) return false;
  return keys.every(
    (key) =>
      Object.prototype.hasOwnProperty.call(b, key) && deepEqual(a[key], b[key]),
  );
}

What an interviewer looks for

It is what a test library's toEqual does, and the opposite of the shallow check React uses. Interviewers score the order of the checks and the edge cases you name without being asked.