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
name
bob
const bob = tom;
Neste caso, a constante bob
tom
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
bob
tom
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()
Object.assign(target, ...sources)
O primeiro parâmetro target
...sources
O método retorna o objeto target
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)
{}
bob
tom
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
sam
person
person
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
sam
age
person
age
sam
sam
Copiando Propriedades-Objeto
Embora o Object.assign()
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
bob
tom.company
bob.company
tom.company
Copiando Objeto com o Operador Spread
O operador spread ...
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
tom
Se algumas propriedades do novo objeto devem ter outros valores (como no exemplo acima a propriedade name
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
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
tom
bob