JavaScript Objects: References, Cloning, and Immutability (Deep vs Shallow)
A deep interview-ready guide to object references in JavaScript: shallow vs deep copies, structuredClone, JSON pitfalls, immutability patterns, and common bugs.
Frontend Interview Team
February 08, 2026
Objects in JS are reference types. Most real-world frontend bugs with state come from misunderstanding references.
This post gives you the mental model + the practical cloning tools.
30‑second interview answer
Objects are reference types, so assignments copy the reference, not the value. A shallow copy copies only the top level; nested objects are still shared. For deep copies, prefer structuredClone when available, or carefully clone via libraries—JSON cloning loses types (Dates, Maps) and breaks functions/undefined. Immutability is crucial in React state to avoid subtle bugs.
Key points
- Shallow copy ≠ deep copy.
- Spread
{...obj}is shallow. structuredCloneis safest general-purpose deep clone.- JSON cloning has many pitfalls.
1) Primitives vs objects (core concept)
Primitives (copied by value):
- string, number, boolean, null, undefined, symbol, bigint
Objects (copied by reference):
- objects, arrays, functions, dates, maps, sets
let a = { x: 1 };
let b = a;
b.x = 2;
console.log(a.x); // 2Because a and b point to the same object.
2) Shallow copy vs deep copy
Shallow copy
Copies only the top-level structure. Nested objects are still shared references.
const obj = { a: 1, nested: { n: 1 } };
const copy = { ...obj };
copy.nested.n = 99;
console.log(obj.nested.n); // 99 (still shared!)Shallow copy tools:
{ ...obj }Object.assign({}, obj)arr.slice()/[...arr]
Deep copy
Copies nested objects too.
3) Best modern option: structuredClone
If your runtime supports it (modern browsers + newer Node):
const deep = structuredClone(obj);Pros:
- handles many built-in types
- avoids many JSON pitfalls
Cons:
- not supported in very old environments
- cannot clone functions
4) JSON cloning (common, but has pitfalls)
const deep = JSON.parse(JSON.stringify(obj));Pitfalls:
- drops
undefined, functions, symbols - converts Date to string
- fails on circular references
- loses Map/Set
Use JSON clone only for simple data.
5) Circular references
const a = {};
a.self = a;
JSON.stringify(a); // TypeErrorIf you expect cycles, use structuredClone or a custom clone.
6) Immutability patterns (frontend interview + React)
Why immutability matters:
- predictable updates
- easier debugging
- change detection (React, Redux) relies on new references
A) Update nested object immutably
const state = { user: { name: 'Rajesh', address: { city: 'Kharar' } } };
const next = {
...state,
user: {
...state.user,
address: {
...state.user.address,
city: 'Toronto'
}
}
};B) Update arrays immutably
const items = [1, 2, 3];
const next = items.map((x) => (x === 2 ? 99 : x));7) When mutation is fine
Mutation is not “evil”. It’s about controlling side effects.
Mutation is okay when:
- object is local and not shared
- you control the lifecycle
- you’re doing performance-critical work in a tight loop
But for state management, prefer immutability.
8) Interview Q&A
Q: Why is [] === [] false?
- different references.
Q: Is {...obj} a deep copy?
- No, it’s shallow.
Q: Best way to deep copy in JS?
structuredClonewhen available; otherwise careful custom clone.
Q: Why do React updates require creating new objects?
- React often uses shallow comparison of references.
Summary checklist
- I can explain reference vs value.
- I can explain shallow vs deep copy.
- I know
structuredCloneis preferred for deep copy. - I can list JSON-clone pitfalls.
Summary
- Objects/arrays are references.
- Spread/Object.assign create shallow copies.
- Use
structuredClonefor deep copy when possible. - JSON cloning has many pitfalls.
- Immutability patterns are essential for frontend apps.