Suggest an editImprove this articleRefine the answer for “Pass by value vs pass by reference”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Primitives (`number`, `string`, `boolean`, `null`, `undefined`, `symbol`, `bigint`) are copied by value, while objects (`object`, `array`, `function`, `Date`, `Map`, `Set`) are copied by reference.** Assigning a primitive creates a new independent copy of the data, so changing one variable never touches the other. Assigning an object copies only the pointer to the same place in memory, so both variables observe the same changes. ```javascript let a = 5; let b = a; // the value is copied b = 10; console.log(a); // 5, unchanged const user1 = { name: 'Maria' }; const user2 = user1; // the reference is copied user2.name = 'Alex'; console.log(user1.name); // "Alex" ``` **Key point:** a primitive copies the data, an object copies only the reference, so an independent object requires an explicit copy (`{ ...obj }` or a deep clone).Shown above the full answer for quick recall.Answer (EN)Image**"By value" means the variable stores the value itself, so copying creates a new independent copy of the data; "by reference" means the variable stores only a pointer to a place in memory, and it is that pointer that gets copied.** In JavaScript primitives behave by value, while objects and every complex data structure behave by reference. ## Theory ### TL;DR - Primitives (`number`, `string`, `boolean`, `null`, `undefined`, `symbol`, `bigint`) are passed by value. - Objects (`object`, `array`, `function`, `Date`, `Map`, `Set` and so on) are passed by reference. - A copy of a primitive is fully independent: changing `b` does not affect `a`. - A copy of an object is the same structure in memory: a change made through one variable is visible through the other. - To get an independent object you need a shallow (`{ ...obj }`) or a deep copy. ### Quick example ```javascript // by value let a = 5; let b = a; // the value 5 is copied b = 10; console.log(a); // 5, unchanged console.log(b); // 10 // by reference const user1 = { name: 'Maria' }; const user2 = user1; // the REFERENCE is copied, not the object itself user2.name = 'Alex'; console.log(user1.name); // "Alex" console.log(user2.name); // "Alex" ``` ### What "by value" means > The variable stores **the value itself**, not a reference to it. > Copying creates **a new independent copy of the data**. Primitives (simple data types) are passed by value. They are: - `number` - `string` - `boolean` - `null` - `undefined` - `symbol` - `bigint` ```javascript let a = 5; let b = a; // the value 5 is copied b = 10; console.log(a); // 5 <- unchanged console.log(b); // 10 ``` `a` and `b` are now two **independent values**, and changing `b` does not affect `a`. ### What "by reference" means > The variable **does not store the object itself**, it stores **a reference (a pointer)** to the place in memory where the object lives. All **objects and complex data structures** are passed by reference: - `object` - `array` - `function` - `Date`, `Map`, `Set` and so on ```javascript const user1 = { name: 'Maria' }; const user2 = user1; // the REFERENCE is copied, not the object itself user2.name = 'Alex'; console.log(user1.name); // "Alex" console.log(user2.name); // "Alex" ``` Both variables point at **one and the same object** in memory, so changing `user2` also changes `user1`. Visually: ```text +------------+ | user1 | --+ +------------+ | v { name: "Maria" } ^ +------------+ | | user2 | --+ +------------+ ``` ### Example with an array An array is an object too, so the same rule applies: ```javascript const arr1 = [1, 2, 3]; const arr2 = arr1; arr2.push(4); console.log(arr1); // [1, 2, 3, 4] console.log(arr2); // [1, 2, 3, 4] ``` Both arrays are **one and the same object** in memory. ### How to copy an object without carrying the reference If you want **a new independent object**, you have to copy the data **explicitly**. A shallow copy (spread): ```javascript const user1 = { name: 'Tim', age: 25 }; const user2 = { ...user1 }; // the spread operator user2.name = 'Alex'; console.log(user1.name); // "Tim" console.log(user2.name); // "Alex" ``` A deep copy (for nested objects): ```javascript const user1 = { name: 'Tim', address: { city: 'Kyiv' } }; const user2 = JSON.parse(JSON.stringify(user1)); // deep cloning user2.address.city = 'Lviv'; console.log(user1.address.city); // "Kyiv" console.log(user2.address.city); // "Lviv" ``` ### Stack, heap and the summary tables | Type | Where it is stored | What happens on copy | | --- | --- | --- | | Primitive (by value) | on the **stack** | **a new copy** is created | | Object (by reference) | on the **heap** | **the reference** to the same place is copied | | Data type | How it is passed | Example | | --- | --- | --- | | `string`, `number`, `boolean`, `null`, `undefined`, `symbol`, `bigint` | **by value** | `let a = 5; let b = a;` | | `object`, `array`, `function`, `Date`, `Map`, `Set` | **by reference** | `let obj2 = obj1;` | In short: - **By value** creates **a copy of the data**. - **By reference** copies **the pointer** to the same object. - That is why changing one object **affects** the other whenever they are linked by a reference. ### Common mistakes - Believing that `const` protects the contents of an object. `const` forbids reassigning the variable, but it does not forbid changing the fields of the object it points at. - Writing `const copy = original` for an object and thinking it is a copy. It is a second name for the very same object. - Confusing a shallow copy with a deep one: `{ ...user }` copies only the top level, nested objects stay shared. - Reaching for `JSON.parse(JSON.stringify(obj))` blindly: it drops `undefined`, functions and `Symbol`, turns a `Date` into a string and throws on circular references. For complex cases prefer `structuredClone(obj)`. - Comparing objects with `===` and expecting `true`: `{ a: 1 } === { a: 1 }` is `false`, because those are two different references.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.