Como copiar um objeto sem referência (Object.assign e spread operator)?
Em JavaScript, os objetos são passados por referência. Isso significa que, quando você cria uma nova variável a partir de um objeto, ambas as variáveis referenciam o mesmo espaço de memória. Ou seja, se você alterar uma das variáveis, a outra também será modificada. Para evitar isso, é importante fazer uma cópia do objeto sem que as duas variáveis compartilhem a mesma referência. Vamos explorar duas maneiras populares de copiar objetos em JavaScript: o método Object.assign()
e o spread operator (...
).
Usando Object.assign()
para copiar objetos
O método Object.assign()
é utilizado para copiar as propriedades de um objeto para outro. Ele cria uma cópia rasa do objeto, o que significa que as propriedades de nível superior são copiadas, mas as propriedades internas (como objetos ou arrays) ainda são passadas por referência.
Exemplo de código com Object.assign()
:
let pessoa = {
nome: 'João',
idade: 25,
endereco: { rua: 'Rua A', numero: 123 }
};
let copiaPessoa = Object.assign({}, pessoa);
console.log(copiaPessoa); // Exibe a cópia do objeto
Neste exemplo, Object.assign({}, pessoa)
cria uma nova cópia do objeto pessoa
e a armazena em copiaPessoa
. Embora copiaPessoa
seja uma cópia do objeto pessoa
, as propriedades internas ainda são passadas por referência.
Características do Object.assign()
- Cópia rasa: As propriedades de nível superior são copiadas, mas objetos e arrays aninhados são copiados por referência.
- Modifica o objeto de destino: O objeto de destino, que é passado como o primeiro argumento, será modificado.
- Não cria cópias profundas: Para objetos complexos,
Object.assign()
não resolve problemas de referências internas.
Usando o spread operator (...
) para copiar objetos
O spread operator (...
) é uma forma mais moderna e concisa de copiar objetos em JavaScript. Ele funciona da mesma forma que Object.assign()
, criando uma cópia rasa do objeto. Também é possível usar o spread operator para copiar propriedades de objetos dentro de uma nova variável.
Exemplo de código com o spread operator:
let pessoa = {
nome: 'João',
idade: 25,
endereco: { rua: 'Rua A', numero: 123 }
};
let copiaPessoa = {...pessoa};
console.log(copiaPessoa); // Exibe a cópia do objeto
Aqui, o spread operator ...pessoa
espalha as propriedades de pessoa
em um novo objeto, criando uma cópia rasa.
Características do Spread Operator
- Sintaxe simples e concisa: O spread operator oferece uma maneira mais compacta e moderna de criar cópias de objetos.
- Cópia rasa: Semelhante ao
Object.assign()
, o spread operator cria uma cópia rasa, ou seja, ele copia as propriedades de nível superior, mas não faz cópias profundas de objetos ou arrays internos. - Não modifica o objeto original: O spread operator cria uma nova referência para o objeto, sem alterar o objeto original.
Diferenças entre Object.assign()
e o Spread Operator
Característica | Object.assign() |
Spread Operator (... ) |
---|---|---|
Sintaxe | Object.assign({}, objeto) |
{...objeto} |
Cópia | Cópia rasa | Cópia rasa |
Acessibilidade | Acessível no ES5 | Acessível no ES6+ |
Flexibilidade | Mais controlado, permite múltiplos objetos como origem | Mais simples e conciso |
Como evitar referências internas (cópias profundas)?
Tanto Object.assign()
quanto o spread operator criam cópias rasas. Se o objeto contiver propriedades que são objetos ou arrays, essas propriedades serão copiadas por referência. Se você modificar um desses objetos internos, a mudança será refletida na cópia também.
Exemplo de código com cópias rasas:
let pessoa = {
nome: 'João',
idade: 25,
endereco: { rua: 'Rua A', numero: 123 }
};
let copiaPessoa = {...pessoa};
console.log(copiaPessoa.endereco === pessoa.endereco); // Exibe true
Aqui, ao copiar pessoa
usando o spread operator, as propriedades internas (como endereco
) ainda são compartilhadas entre o objeto original e a cópia, pois a cópia é rasa.
Para fazer cópias profundas (onde objetos internos também são copiados de forma independente), você pode usar JSON.parse()
e JSON.stringify()
ou implementar uma função de clonagem recursiva.
Exemplo de cópia profunda:
let pessoa = {
nome: 'João',
idade: 25,
endereco: { rua: 'Rua A', numero: 123 }
};
let copiaProfundaPessoa = JSON.parse(JSON.stringify(pessoa));
console.log(copiaProfundaPessoa.endereco === pessoa.endereco); // Exibe false
Aqui, JSON.parse(JSON.stringify())
cria uma cópia profunda do objeto pessoa
, o que significa que as propriedades internas também são copiadas de forma independente.
Quando usar Object.assign()
ou o Spread Operator?
- Use
Object.assign()
quando você precisar de mais controle sobre a cópia, como quando estiver copiando múltiplos objetos ou combinando dados. - Use o spread operator quando desejar uma sintaxe mais compacta e legível, especialmente para copiar um único objeto.
Conclusão
Copiar objetos sem referência é essencial quando você precisa garantir que a modificação de um objeto não afete outro. O método Object.assign()
e o spread operator são maneiras eficazes de criar cópias rasas de objetos. Ambos oferecem soluções simples, mas lembre-se de que eles não fazem cópias profundas. Se precisar de cópias independentes de objetos internos, considere usar outras abordagens como JSON.parse()
/JSON.stringify()
ou funções de clonagem personalizadas.
Quando usar Object.assign() ou o Spread Operator para copiar objetos sem referência
Ao lidar com objetos em JavaScript, entender como copiar objetos sem referência é fundamental para evitar alterações não intencionais. A cópia rasa criada pelo Object.assign()
e pelo spread operator é adequada para a maioria dos casos, mas em situações onde é necessário preservar objetos internos de maneira independente, a cópia profunda se torna essencial. O conhecimento dessas técnicas permitirá que você crie soluções mais robustas e seguras ao manipular dados em seus aplicativos.
Algumas aplicações:
- Criar cópias de objetos para evitar mudanças indesejadas no objeto original.
- Copiar dados para diferentes estados ou contextos sem afetar o estado original.
- Manipular dados de maneira segura em APIs ou ao trabalhar com dados de usuários e configurações.
- Usar cópias rasas e profundas para manipular dados de forma eficiente em aplicativos dinâmicos.
Dicas para quem está começando
- Use o spread operator quando precisar de uma solução rápida e legível para copiar objetos.
- Se o seu objeto contém propriedades aninhadas (como objetos ou arrays), lembre-se de que o spread operator e
Object.assign()
fazem cópias rasas, e você pode precisar de uma cópia profunda. - Para cópias profundas, use a técnica de
JSON.parse()
eJSON.stringify()
ou crie sua própria função de clonagem. - Experimente combinar
Object.assign()
com outros objetos para aprender a criar cópias complexas e fundir dados de diferentes fontes.
Contribuições de Lucas Souza