Atualizado: 07/12/2024

Copiando e Comparando Objetos - JavaScript

Copiando Objetos

Ao contrário dos dados de tipos primitivos, os dados dos objetos são copiados por referência. O que isso significa? Vamos considerar o seguinte exemplo:

const tom = {name: "Tom"};
const bob = tom;

// verificamos a propriedade name em ambas as constantes
console.log(tom.name);  // Tom
console.log(bob.name);  // Tom
            
// alteramos a propriedade name na constante bob
bob.name = "Bob";

// verificamos novamente a propriedade name em ambas as constantes
console.log("Após a mudança")
console.log(tom.name);  // Bob
console.log(bob.name);  // Bob

Inicialmente, um objeto comum tom é definido com uma propriedade name. Então, o valor desse objeto é atribuído à constante bob:

const bob = tom;

Neste caso, a constante bob recebe uma referência ou, por assim dizer, o endereço da constante tom, portanto, após essa atribuição, ambas as constantes essencialmente apontam para o mesmo objeto na memória. Consequentemente, as mudanças feitas através de uma constante:

bob.name = "Bob";

Serão refletidas na outra constante:

console.log(tom.name);  // Bob

Além disso, vamos adicionar uma nova propriedade ao objeto por meio de uma das constantes:

const tom = { name: "Tom" };
const bob = tom;

// adicionamos à constante bob uma nova propriedade - age
bob.age = 37;

// e vemos que para tom também foi adicionada uma nova propriedade
console.log(tom.age);   // 37

Após adicionar a propriedade age à constante bob, podemos ver que na constante tom essa propriedade também apareceu, porque novamente ambas as constantes representam o mesmo objeto.

Mas e se quisermos copiar de uma propriedade do objeto, mas ao mesmo tempo ambas as constantes ou variáveis apontassem para objetos completamente diferentes, mudanças em um dos quais de forma alguma afetariam o outro? Nesse caso, podemos usar o método integrado Object.assign().

Método Object.assign

O método Object.assign() aceita dois parâmetros:

Object.assign(target, ...sources)

O primeiro parâmetro target representa o objeto ao qual as propriedades devem ser copiadas. O segundo parâmetro ...sources é um conjunto de objetos dos quais as propriedades devem ser copiadas (ou seja, podemos copiar propriedades de vários objetos ao mesmo tempo)

O método retorna o objeto target, no qual as propriedades dos objetos sources foram copiadas.

Por exemplo:

const tom = { name: "Tom", age: 37 };
const bob = Object.assign({}, tom);
bob.name = "Bob";
bob.age = 41;
            
console.log(`Objeto tom. Name: ${tom.name}   Age: ${tom.age}`);
console.log(`Objeto bob. Name: ${bob.name}   Age: ${bob.age}`);

Neste caso, a chamada Object.assign({}, tom) significa que estamos copiando dados do objeto tom para um objeto vazio {}. O resultado dessa cópia foi o objeto bob. E este é um objeto completamente diferente de tom. E quaisquer alterações na constante bob aqui de forma alguma afetarão a constante tom.

Saída no console do navegador:

Objeto tom. Name: Tom   Age: 37
Objeto bob. Name: Bob   Age: 41

Copiando de Vários Objetos

Da mesma forma, podemos copiar dados de vários objetos:

const tom = { name: "Tom" };
const sam = { age: 37 };
const person = { height: 170 };
Object.assign(person, tom, sam);    // copiamos de tom e sam para person
console.log(person);    // { height: 170, name: "Tom", age: 37 }

Aqui, todas as propriedades dos objetos tom e sam são copiadas para o objeto person. Como resultado, após a cópia, o objeto person terá três propriedades.

Copiando Propriedades com o Mesmo Nome

Se os objetos dos quais a cópia é realizada contêm propriedades iguais, as propriedades dos objetos mais recentes substituirão as propriedades dos anteriores:

const tom = { name: "Tom", age: 37 };
const sam = { age: 45 };
const person = { height: 170 };
Object.assign(person, tom, sam);
console.log(person);    // { height: 170, name: "Tom", age: 45 }

Aqui, ambos os objetos tom e sam contêm a propriedade age, mas no objeto person, a propriedade age é 45, que é o valor do objeto sam, porque a cópia do objeto sam é feita por último.

Copiando Propriedades-Objeto

Embora o Object.assign() funcione bem para objetos simples, o que acontece se a propriedade do objeto copiado também for um objeto:

const tom = { name: "Tom", company: { title: "Microsoft" } };
const bob = Object.assign({}, tom);
bob.name = "Bob";
bob.company.title = "Google";
console.log(tom.name);      // Tom
console.log(tom.company.title);     // Google

Aqui, a propriedade company do objeto tom é um objeto com uma propriedade. E na cópia, o objeto bob recebe não uma cópia do valor tom.company, mas uma referência a esse objeto. Portanto, mudanças em bob.company afetarão tom.company.

Copiando Objeto com o Operador Spread

O operador spread ... permite desmembrar um objeto em diversos pares propriedade-valor, que podem ser passados a outro objeto:

const tom = { name: "Tom", age: 37, company: "Google" };
const bob = { ...tom }
bob.name = "Bob";
            
console.log(tom);   // { name: "Tom", age: 37, company: "Google" }
console.log(bob);   // { name: "Bob", age: 37, company: "Google" }

Neste caso, ao objeto bob são passadas cópias das propriedades do objeto tom.

Se algumas propriedades do novo objeto devem ter outros valores (como no exemplo acima a propriedade name), elas podem ser especificadas no final:

const tom = { name: "Tom", age: 37, company: "Google" };
const bob = { ...tom, name: "Bob" };
            
console.log(bob);   // { name: "Bob", age: 37, company: "Google" }

Como visto no exemplo anterior, ambas as constantes após a cópia representam links para diferentes objetos, e mudanças em um deles de forma alguma afetarão o outro objeto.

No entanto, se os objetos contêm objetos aninhados, esses objetos aninhados, ao serem copiados, novamente, na verdade representarão links para o mesmo objeto:

const tom = { name: "Tom", age: 37, company: { title: "Microsoft" } };
const bob = { ...tom }
bob.name = "Bob";
bob.company.title = "Google";
    
console.log(`${tom.name} - ${tom.company.title}`);  // Tom - Google
console.log(`${bob.name} - ${bob.company.title}`);  // Bob - Google

Comparação de Objetos

Vamos comparar dois objetos usando as operações padrão de comparação e equivalência:

const tom = { name: "Tom" };
const bob = { name: "Bob" };
console.log(tom == bob);    // false
console.log(tom === bob);   // false

Ambos os operadores, neste caso, retornarão false, ou seja, os objetos não são iguais. Mesmo que os valores das propriedades dos objetos sejam iguais, ainda assim, em ambos os casos, obteremos false:

const tom = { name: "Tom" };
const bob = { name: "Tom" };
console.log(tom == bob);    // false
console.log(tom === bob);   // false

No entanto, o que acontecerá se ambas as constantes (variáveis) armazenarem uma referência para o mesmo objeto:

const tom = { name: "Tom" };
const bob = tom;
console.log(tom == bob);    // true
console.log(tom === bob);   // true

Neste caso, ambos os operadores retornarão true, porque ambas as constantes tom e bob armazenam uma referência para o mesmo objeto.

Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com