What is the difference between deep equality and shallow equality?
Equality checks can compare just the surface or every nested level.
Shallow equality — compares top-level values/references only. Two different objects with identical contents are not equal.
Deep equality — recursively compares every nested property, so structurally identical objects count as equal.
Note: JavaScript has no built-in deep-equal — use a library (e.g. Lodash isEqual) or a recursive comparison.
// Shallow equality
function shallowEqual(obj1, obj2) {
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
return keys1.every(key => Object.is(obj1[key], obj2[key]));
}
const a = { x: 1, y: { z: 2 } };
const b = { x: 1, y: { z: 2 } };
const c = { x: 1, y: a.y }; // Same reference for y
console.log(shallowEqual(a, b)); // false (y objects are different references)
console.log(shallowEqual(a, c)); // true (y is the same reference)
// Deep equality
function deepEqual(obj1, obj2) {
if (obj1 === obj2) return true;
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;
if (obj1 === null || obj2 === null) return false;
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
return keys1.every(key => deepEqual(obj1[key], obj2[key]));
}
console.log(deepEqual(a, b)); // true (same content at all levels)shallowEqual compares top-level values with Object.is — nested objects are compared by reference (a.y !== b.y). deepEqual recursively compares nested objects by content (a.y and b.y have the same structure and values). React uses shallow equality — this is why creating new objects in render ({}) defeats React.memo.
Implement both from scratch — common coding question. Shallow: top-level Object.is comparison.
Deep: recursive comparison. Know that React uses shallow equality (why new objects in render cause re-renders). structuredClone + === is NOT deep equality — it is deep copy + reference check.