Skip to main content

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 } or Object.assign({}, obj).
  • For a deep copy use structuredClone(obj) or _.cloneDeep(obj).

Quick example

javascript
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

text
Memory: +---------------------+ | { name: 'Alice' } | +----------+----------+ ^ | +-- user +-- clone

Both 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 typeHow 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
javascript
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 reference

Note 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 needHow to do it
Shallow copy{ ...obj } or Object.assign({}, obj)
Deep copystructuredClone(obj) or _.cloneDeep(obj)

Example:

javascript
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 = aExplanation
Primitives (numbers, strings and so on)The value is copied
Objects, arrays, functionsThe reference is copied, not the contents
Changing the copy affects the originalYes, if it is an object
How to avoid itUse spread ({ ...obj }) or structuredClone()

Common mistakes

  • Assuming const protects the object from changes. const only freezes the binding, the object's contents stay mutable.
  • Comparing objects with === and expecting a comparison by contents. { x: 1 } === { x: 1 } is false, because references are compared, while user === clone after = is true.
  • 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 = state in 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 ready
Premium

A concise answer to help you respond confidently on this topic during an interview.