In JavaScript, shallow comparison refers to comparing the references of two objects rather than their actual content. When performing a shallow comparison, you're essentially checking if two variables reference the same object in memory. For example:
const obj1 = { foo: 'bar' }; const obj2 = { foo: 'bar' }; const obj3 = obj1; console.log(obj1 === obj2); // false — different objects with the same content console.log(obj1 === obj3); // true — `obj1` and `obj3` reference the same object
In this example, although identical, "obj1
" and "obj2
" are considered different because they don't point to the same object reference in memory. In contrast, "obj1
" and "obj3
" are considered the same as they refer to the same object in memory.
This concept extends to all objects such as functions, arrays, and other non-primitive values, as you can see in the following example:
const arr1 = [1, 2, 3]; const arr2 = [1, 2, 3]; const arr3 = arr1; console.log(arr1 === arr2); // false console.log(arr1 === arr3); // true
const fn1 = () => 'foo'; const fn2 = () => 'foo'; const fn3 = fn1; console.log(fn1 === fn2); // false console.log(fn1 === fn3); // true
Shallow Comparison of Deep Nested Objects
In a shallow comparison, JavaScript compares if two variables point to the same memory location, rather than checking whether the actual data within those objects is identical. This means that only comparing the top-level references of the objects is sufficient to determine their equality. For example:
const obj1 = { a: 1, b: { c: 2 } }; const obj2 = { a: 1, b: { c: 2 } }; const obj3 = obj1; console.log(obj1 === obj2); // false — different objects with the same content console.log(obj1 === obj3); // true — `obj1` and `obj3` reference the same object
Consider another example where the top-level references of two objects are different but the nested objects within them point to the same reference in memory:
const nestedObj = { c: 2 }; const obj1 = { a: 1, b: nestedObj }; const obj2 = { a: 1, b: nestedObj }; console.log(obj1 === obj2); // false — different top-level objects console.log(obj1.b === obj2.b); // true — same nested object reference
As you can see in this example, although "obj1
" and "obj2
" are not equal, the nested object "nestedObj
" within them share the same reference in memory, resulting in equality when compared directly.
In this case, modifying the nested object would not break the nested equality because both nested objects refer to the same object in memory:
// ... nestedObj.c = 3; console.log(obj1.b === obj2.b); // true — still the same nested object reference console.log(obj1.b.c === obj2.b.c); // true — same values for nested property 'c'
Does Shallow Comparison Apply to Primitives?
Primitives data types, such as strings, numbers, booleans, symbols, etc. are compared by their actual value, rather than by reference. Since primitives directly hold their value rather than referring to another location in memory, there is no distinction between a shallow and deep comparison for them.
When you compare primitive values, JavaScript checks if the values are the same. If they're indeed identical, the comparison evaluates to true
; otherwise, it evaluates to false
. For example:
const a = 5; const b = 5; const c = 'hello'; const d = 'hello'; console.log(a === b); // true — `a` and `b` have the same value console.log(c === d); // true — `c` and `d` have the same value
This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.