Copiando um objeto sem referência em JavaScript: Object.assign vs Spread Operator

Descubra como copiar objetos em JavaScript sem referência usando Object.assign() e o spread operator para evitar modificações indesejadas no objeto original.

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.

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() e JSON.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

Compartilhe este tutorial: Como copiar um objeto sem referência (Object.assign e spread operator)?

Compartilhe este tutorial

Continue aprendendo:

Como verificar se um objeto possui uma propriedade (hasOwnProperty)?

Descubra como usar o método `hasOwnProperty()` para verificar se um objeto em JavaScript contém uma propriedade específica, sem herdar propriedades da cadeia de protótipos.

Tutorial anterior

Como mesclar dois objetos (Object.assign e spread operator)?

Descubra como mesclar dois ou mais objetos em JavaScript usando `Object.assign()` ou o spread operator para combinar suas propriedades.

Próximo tutorial