Question
I have a JavaScript object x, and I want to create a copy called y so that changing y does not affect x.
I noticed that copying objects can be tricky because JavaScript objects are assigned by reference. I am working with my own object created using an object literal, not with complex built-in objects.
How can I correctly clone a JavaScript object in JavaScript?
Short Answer
By the end of this page, you will understand why assigning one object to another does not create a copy in JavaScript, the difference between shallow and deep cloning, and the most common ways to clone objects safely using modern JavaScript.
Concept
In JavaScript, objects are reference types. That means when you do this:
const x = { name: "Alice" };
const y = x;
both x and y point to the same object in memory. If you change y.name, x.name changes too, because there is only one object.
To make an actual copy, you need to clone the object.
There are two main kinds of cloning:
Shallow clone
A shallow clone copies only the top-level properties.
const x = { name: "Alice", address: { city: "Paris" } };
const y = { ...x };
Now x and y are different objects, but nested objects like address are still shared.
Deep clone
A deep clone copies the object and all nested objects inside it.
const x = { name: "Alice", address: { : } };
y = (x);
Mental Model
Think of an object like a house address written on a card.
- A variable does not contain the whole house.
- It contains the address of the house.
- If you copy the card, both cards still point to the same house.
const x = { color: "blue" };
const y = x;
x and y are two cards with the same address.
If you paint the house through y, the house seen through x is also changed.
A shallow clone is like building a new house but reusing some of the furniture from the old house.
A deep clone is like building a new house and also making brand-new copies of all the furniture inside it.
Syntax and Examples
Common ways to clone an object
1. Shallow clone with spread syntax
const original = { name: "Alice", age: 25 };
const copy = { ...original };
copy.name = "Bob";
console.log(original.name); // Alice
console.log(copy.name); // Bob
This works well for simple, flat objects.
2. Shallow clone with Object.assign()
const original = { name: "Alice", age: 25 };
const copy = Object.assign({}, original);
copy.age = 30;
console.log(original.age); // 25
console.log(copy.age); // 30
Step by Step Execution
Consider this example:
const x = {
user: "Sam",
settings: {
theme: "dark"
}
};
const y = { ...x };
y.settings.theme = "light";
console.log(x.settings.theme);
console.log(y.settings.theme);
Step by step
1. Create x
const x = {
user: "Sam",
settings: {
theme: "dark"
}
};
x points to an object with two properties:
user→ a stringsettings→ another object
2. Create y using spread syntax
Real World Use Cases
Object cloning appears in many everyday JavaScript tasks.
Updating UI state
Frameworks and state management patterns often rely on creating copies instead of mutating existing objects.
const state = { count: 1 };
const nextState = { ...state, count: 2 };
Preparing API data
You may want to copy server data before transforming it.
const userFromApi = { name: "Ana", active: true };
const editableUser = { ...userFromApi };
Function safety
If a function should not change its input, clone the object first.
function normalizeUser(user) {
const copy = { ...user };
copy.name = copy.name.trim();
return copy;
}
Data processing pipelines
When processing lists of records, cloning helps preserve original data.
updatedProducts = products.( ({
...product,
:
}));
Real Codebase Usage
In real projects, developers rarely clone objects just for the sake of cloning. They clone objects to support safer patterns.
Immutable updates
A common pattern is to return a new object instead of changing the old one.
function updateProfile(profile, newEmail) {
return { ...profile, email: newEmail };
}
Nested updates
When nested data is involved, developers often clone each level they are updating.
const updatedUser = {
...user,
settings: {
...user.settings,
theme: "light"
}
};
This avoids unwanted shared references.
Guarding function inputs
Some functions clone inputs when they must safely transform data without side effects.
function prepareOptions(options = {}) {
return {
...options,
retry: options.retry ?? 3
};
}
Configuration merging
Spread syntax is often used to combine defaults with custom options.
Common Mistakes
1. Thinking assignment creates a copy
const a = { value: 1 };
const b = a;
b.value = 2;
console.log(a.value); // 2
b = a does not clone the object. It copies the reference.
2. Using a shallow clone for nested objects
const a = { nested: { value: 1 } };
const b = { ...a };
b.nested.value = 2;
console.log(a.nested.value); // 2
Avoid this by using deep cloning when nested data must be independent.
3. Relying on JSON cloning for all data
Broken example:
const a = {
createdAt: new Date(),
greet: () => ,
:
};
b = .(.(a));
.(b);
Comparisons
Object cloning approaches
| Approach | Clone type | Good for | Limitations |
|---|---|---|---|
const y = x | No clone | Sharing the same object intentionally | Changes affect both variables |
{ ...x } | Shallow | Plain objects, top-level updates | Nested objects are shared |
Object.assign({}, x) | Shallow | Similar to spread syntax | Nested objects are shared |
structuredClone(x) | Deep | Nested data, safer full copies | Environment support must exist; not for every special case |
JSON.parse(JSON.stringify(x)) |
Cheat Sheet
Quick reference
Assignment does not clone
const y = x;
xandypoint to the same object
Shallow clone
const y = { ...x };
const y2 = Object.assign({}, x);
- copies only top-level properties
- nested objects remain shared
Deep clone
const y = structuredClone(x);
- copies nested objects too
- best modern built-in option for many cases
JSON clone
const y = JSON.parse(JSON.stringify(x));
- works only for simple JSON-safe data
- loses functions,
undefined, and special object types
Nested update pattern
FAQ
Why does const y = x not copy an object in JavaScript?
Because objects are stored by reference. The variable gets a reference to the same object, not a separate duplicate.
What is the easiest way to clone a simple object in JavaScript?
For a plain flat object, use spread syntax:
const copy = { ...original };
Does spread syntax create a deep copy?
No. It creates a shallow copy only. Nested objects and arrays are still shared.
When should I use structuredClone()?
Use it when you need a deep copy of nested data and your environment supports it.
Is JSON.parse(JSON.stringify(obj)) a good cloning method?
Only for simple JSON-style data. It breaks or removes some values, so it is not a general-purpose cloning solution.
How do I clone a nested object without sharing inner properties?
Use structuredClone() or manually clone each nested level you need to update.
Are arrays cloned the same way as objects?
They follow the same reference rules. Use:
const copy = [...array];
for a shallow array clone.
Mini Project
Description
Build a small profile editor that copies a user object before making changes. This project demonstrates the difference between shallow and deep cloning, especially when nested settings are involved.
Goal
Create a program that safely edits a copied user profile without changing the original object.
Requirements
[ "Create a user object with at least one nested object property.", "Make one shallow copy and one deep copy of the user object.", "Modify nested data in each copy.", "Print the original object and both copies to compare the results.", "Use modern JavaScript syntax." ]
Keep learning
Related questions
Deep Cloning Objects in JavaScript: Methods, Trade-offs, and Best Practices
Learn how to deep clone objects in JavaScript, compare structuredClone, JSON methods, and recursive approaches with examples.
Get Screen, Page, and Browser Window Size in JavaScript
Learn how to get screen size, viewport size, page size, and scroll position in JavaScript across major browsers with clear examples.
How JavaScript Closures Work: A Beginner-Friendly Guide
Learn how JavaScript closures work with simple explanations, examples, common mistakes, and practical use cases for real code.