Why the = operator does not copy an object
The = operator does not copy an object, it only copies the reference to it in memory, so both variables point at the very same object. That is exactly why the "copy" is not independent: any change made through one variable is immediately visible through the other.
Theory
TL;DR
- For an object,
=copies the reference, not the contents. - After
const clone = user, both variables point at one object in memory. - Primitives are assigned by value, while objects, arrays and functions are assigned by reference.
- That is why changing the "copy" also changes the original.
- For a shallow copy use
{ ...obj }orObject.assign({}, obj). - For a deep copy use
structuredClone(obj)or_.cloneDeep(obj).
Quick example
const user = { name: 'Alice' };
const clone = user; // "copying" the object
clone.name = 'Oleh';
console.log(user.name); // 'Oleh'
console.log(clone.name); // 'Oleh'The change on clone changed user too, because it is one and the same object in memory.
What this looks like under the hood
Memory:
+---------------------+
| { name: 'Alice' } |
+----------+----------+
^
|
+-- user
+-- cloneBoth user and clone are references to the same object. When you write const clone = user, one more reference is created, not a new copy. The object itself lives in the heap as a single instance, and the variables hold only its address.
Why this happens
JavaScript has two kinds of data when it comes to assignment:
| Data type | How it is copied |
|---|---|
Primitives (number, string, boolean, null, undefined, symbol, bigint) | by value |
Reference types (object, array, function, Map, Set and so on) | by reference |
let a = 5;
let b = a;
b = 10;
console.log(a); // 5, a copy of the value
const obj1 = { x: 1 };
const obj2 = obj1;
obj2.x = 2;
console.log(obj1.x); // 2, a shared referenceNote that const does not help here. const forbids reassigning the variable itself, but it does not forbid changing the contents of the object it points to.
When you really need a copy
Use one of these options:
| What you need | How to do it |
|---|---|
| Shallow copy | { ...obj } or Object.assign({}, obj) |
| Deep copy | structuredClone(obj) or _.cloneDeep(obj) |
Example:
const user = { name: 'Alice' };
const clone = { ...user }; // creates a new object
clone.name = 'Oleh';
console.log(user.name); // "Alice"
console.log(clone.name); // "Oleh"Now the objects are independent.
Summary table
What happens on const b = a | Explanation |
|---|---|
| Primitives (numbers, strings and so on) | The value is copied |
| Objects, arrays, functions | The reference is copied, not the contents |
| Changing the copy affects the original | Yes, if it is an object |
| How to avoid it | Use spread ({ ...obj }) or structuredClone() |
Common mistakes
- Assuming
constprotects the object from changes.constonly freezes the binding, the object's contents stay mutable. - Comparing objects with
===and expecting a comparison by contents.{ x: 1 } === { x: 1 }isfalse, because references are compared, whileuser === cloneafter=istrue. - Passing an object into a function and mutating it there. The argument is the same reference, so the call changes the object at the call site.
- Writing
const copy = statein React or Redux. The reference does not change, so no re-render happens and the state is mutated directly. - Stopping at spread for nested structures.
{ ...obj }copies only the top level, and nested objects are still shared.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.