JavaScript objects don’t behave the way many people expect. Can you guess what the output of the following code?
const users = [
{ id: 1, name: "John" },
{ id: 2, name: "Jane" }
];
const foundUser = users.find(u => u.id === 1);
foundUser.name = "Updated John";
console.log(users);
✔ The output of the code above will be:
[
{ id: 1, name: "Updated John" },
{ id: 2, name: "Jane" }
]
This surprises many people, but it is completely expected behavior in JavaScript.
🤔Why this happens?
→ Arrays in JavaScript store references to objects
→ Array.find() returns the actual object, not a copy
→ Objects are reference types, not value types
So after this line:
const foundUser = users.find(u => u.id === 1);
👉 Both of these point to the same object in memory:
users[0] ────┐
├──► { id: 1, name: "John" }
foundUser ───┘
👉 When you do:
foundUser.name = "Updated John";
You are mutating that shared object.
Since the array holds a reference to the same object, the array reflects the change.
💡 A safer approach is to update immutably (create a new array and a new object):
const updatedUsers = [];
const updatedUsers = users.map(user =>
user.id === 1 ? { ...user, name: "Updated John" } : user
);
▶ But remember: { ...user } is a shallow copy. If user contains nested objects, those nested references are still shared. In that case, you must copy the nested structure you modify, or use a deep clone.
▶ There is another option which is called structuredClone().
This function returns a deep copy of the object you are passing as an argument.
const copy = structuredClone(user);
Now mutating copy won’t affect the original object.
Top comments (0)