What is the difference between a shallow copy and a deep copy?
Show answer — try answering out loud first
A shallow copy only copies the top level; nested objects or arrays still share the same reference. A deep copy copies everything, including the nested levels, creating fully independent objects.
When you copy an object with spread ({...obj}) or Object.assign, you get a shallow copy: the top-level properties are new, but if there's another object or array inside, that one stays the same (they share a reference). Modifying the nested object in the copy also affects the original.
A deep copy clones everything, all the way down, so the original and the copy are completely separate.
Ways to make a deep copy:
structuredClone(obj)— the modern, recommended approach.JSON.parse(JSON.stringify(obj))— it works, but it loses functions andundefined, turns dates into strings, etc.
// Shallow copy: the nested level is shared
const original = {
nombre: "Mike",
direccion: { ciudad: "Ciudad de México" },
};
const superficial = { ...original };
superficial.nombre = "Alguien"; // only affects the copy
superficial.direccion.ciudad = "Puebla"; // affects BOTH
console.log(original.nombre); // "Mike" (independent)
console.log(original.direccion.ciudad); // "Puebla" (the reference was shared)
// Deep copy with structuredClone
const original2 = { direccion: { ciudad: "Ciudad de México" } };
const profunda = structuredClone(original2);
profunda.direccion.ciudad = "Monterrey";
console.log(original2.direccion.ciudad); // "Ciudad de México" (intact)
console.log(profunda.direccion.ciudad); // "Monterrey"
Thinking that {...obj} or Object.assign make a full copy. They only copy the top level. If the object has nested data, modifying it in the "copy" also changes the original, which causes bugs that are very hard to track down.
"A shallow copy, like the one I make with the spread operator, only copies the top level; nested objects or arrays still point to the same reference, so modifying them affects the original. A deep copy clones everything all the way down and leaves the objects completely independent. For a deep copy I use
structuredClone, which is the modern approach;JSON.parse(JSON.stringify())used to be used, but that loses functions and turns dates into strings."
What does this print?
const a = { lista: [1, 2] };
const b = { ...a };
b.lista.push(3);
console.log(a.lista);
See answer
It prints [1, 2, 3]. The spread makes a shallow copy, so a.lista and b.lista are the same array. Calling push on b.lista also changes the one on a.