Suggest an editImprove this articleRefine the answer for “Why the = operator does not copy an object”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**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.** The reason is that primitives (`number`, `string`, `boolean`, `null`, `undefined`, `symbol`, `bigint`) are assigned by value, while objects, arrays, functions, `Map` and `Set` are assigned by reference. That is why changing the "copy" also changes the original. To get a real copy you need spread `{ ...obj }` or `Object.assign({}, obj)` for the top level, or `structuredClone(obj)` or `_.cloneDeep(obj)` for a deep copy. ```javascript const user = { name: 'Alice' }; const clone = user; // not a copy, a second reference clone.name = 'Oleh'; console.log(user.name); // 'Oleh' console.log(clone.name); // 'Oleh' ``` **Key point:** `=` creates another name for the same object, not a new object.Shown above the full answer for quick recall.Answer (EN)Image**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 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 | ```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 need | How to do it | | --- | --- | | Shallow copy | `{ ...obj }` or `Object.assign({}, obj)` | | Deep copy | `structuredClone(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 = 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 `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.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.