Cópia superficial e cópia profunda são dois assuntos presentes no cotidiano de programadores de linguagens como C e C++, mas que talvez não tenham tanta recorrência para os programadores JavaScript.
Shallow Copy
Em uma explicação rápida, a cópia superficial tem por objetivo copiar objetos fazendo com que propriedades primitivas de alto nível tenham referências diferentes.
Se algo primitivo for alterado no mais alto nível do objeto copiado não fará nenhuma diferença para a cópia.
Deep Copy
Ja a cópia profunda não mantém nenhum tipo de referência entre o objeto copiado e a sua cópia.
Em outras palavras, tanto para propriedades primitivas de alto nível, como para outros objetos aninhados, a referência nunca será a mesma.
const origin = {
value: "X",
object: {
value: "Y",
},
date: new Date(),
};
// Associação por referência
// Basicamente um apontamento para um objeto.
const copy1 = origin;
// Shallow Copy
// Propriedades primitivas de nível superior não mantém a mesma referência do objeto copiado.
// Propriedades aninhadas que são consideradas objetos mantém a mesma referência do objeto copiado.
const copy2 = Object.assign({}, origin);
// Deep Copy
// Nenhum tipo de propriedade mantém a mesma referência.
// JSON.stringify
// Funciona com objetos, arrays e todos os primitivos.
// Alguns tipos de dados não são copiados corretamente, como por exemplo as datas (Date).
const copy3 = JSON.parse(JSON.stringify(origin));
origin.value = "A";
origin.object.value = "B";
origin.date.setMinutes(0);
console.log(
"\n",
`${print(copy1)}\n`,
`${print(copy2)}\n`,
`${print(copy3)}\n`,
);
function print(o) {
return `value: ${o.value} | object.value: ${o.object.value} | date: ${o.date}`;
}
O resultado é algo próximo de:
value: A | object.value: B | date: Thu Mar 28 2024 00:00:22 GMT+0000 (Coordinated Universal Time)
value: X | object.value: B | date: Thu Mar 28 2024 00:00:22 GMT+0000 (Coordinated Universal Time)
value: X | object.value: Y | date: 2024-03-28T00:35:22.649Z
Caso você não queira implementar seu próprio algoritmo, o structuredClone pode ser uma opção.
Saiba que, assim como o JSON.stringify
, ele apresenta limitações.
Entenda mais sobre o assunto lendo os seguintes artigos:
Deep copy
JavaScript language overview
Object copying
Shallow copy