Копирование и сравнение объектов

Последнее обновление: 02.09.2021

Копирование объектов

В отличие от данных примитивных типов данные объектов копируются по ссылке. Что это значит? Рассмотрим следующий пример:

const tom = { name: "Tom"};
const bob = tom;
// проверяем свойство name у обоих констант
console.log(tom.name);	// Tom
console.log(bob.name);	// Tom
		
// меняем свойство name у константы bob
bob.name = "Bob";
// повторно проверяем свойство name у обоих констант
console.log("После изменения")
console.log(tom.name);	// Bob
console.log(bob.name);	// Bob

Вначале определяется обычный объект tom с одним свойством name. Затем присваиваем значение этого объекта константе bob

const bob = tom;

В данном случае константа bob получае ссылку или условно говоря адрес константы tom, поэтому после этого присвоения обе константы по сути указывают на один и тот же объект в памяти. Соответственно изменения, произведенные через одну константу:

bob.name = "Bob";

Затронут и другую константу - tom:

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

Более того, добавим к объекту новое свойство через одну из констант:

const tom = { name: "Tom"};
const bob = tom;
// добавляем константе bob новое свойство - age
bob.age = 37;
// и видим, что для tom тоже добавлено новое свойство
console.log(tom.age);	// 37

После добавления свойства age константе bob можно увидеть, что у константы tom то же появилось это свойство, потому что опять же обе константы представляют один и тот же объект.

Что же если мы хотим скопировать из свойства объекта, но при этом обе константы или переменных указывали бы на совершенно разные объекты, изменения одного из которых никак бы не затрагивали другой? В этом случае мы можем воспользоваться встроенным методом Object.assign().

Метод Object.assign

Метод Object.assign() принимает два параметра:

Object.assign(target, ...sources)

Первый параметр - target представляет объект, в который надо скопировать свойства. Второй параметр - ...sources - набор объектов, из которых надо скопировать свойства (то есть мы можем скопировать свойства сразу из нескольких объектов)

Возвращает метод объект target, в который скопированы свойства из объектов sources.

Например:

const tom = { name: "Tom", age: 37};
const bob = Object.assign({}, tom);
bob.name = "Bob";
bob.age = 41;
		
console.log(`Объект tom. Name: ${tom.name}   Age: ${tom.age}`);
console.log(`Объект bob. Name: ${bob.name}   Age: ${bob.age}`);

В данном случае вызов Object.assign({}, tom) означает, что мы копируем данные из объекта tom в пустой объект {}. Результатом этого копирования стал объект bob. Причем это совсем другой объект, нежели tom. И любые изменения с константой bob здесь никак не затронут константу tom.

Консольный вывод программы:

Объект tom. Name: Tom   Age: 37
Объект bob. Name: Bob   Age: 41

Копирование из нескольких объектов

Подобным образом можно копировать данные из нескольких объектов:

const tom = { name: "Tom"};
const sam = { age: 37};
const person = { height: 170};
Object.assign(person, tom, sam);	// копируем из tom и sam в person
console.log(person);	// {height: 170, name: "Tom", age: 37}

Здесь копируются все свойства из объектов tom и sam в объект person. В итоге после копирования объект person будет иметь три свойства.

Копирование одноименных свойств

Если объекты, из которых выполняется копирование, содержат одинаковые свойства, то свойства из последних объектов замещают свойства предыдущих:

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}

Здесь оба объекта - tom и sam содержат свойство age, но в объекте person свойство age равно 45 - значение из объекта sam, потому что копирование из объекта sam произодится в последнюю очередь.

Копирование свойств-объектов

Несмотря на то, что 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

Здесь свойство company объекта tom представляет объект с одним свойством. И при копировании объект bob получит не копию значения tom.company, а ссылку на этот объект. Поэтому изменения bob.company затронут и tom.company.

Копирование объекта с помощью spread-оператора

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"}

В данном случае объекту bob передаются копии свойств объекта tom.

Если какие-то свойства нового объекта должны иметь другие значения (как в примере выше свойство name), то их можно указать в конце:

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

Как видно из предыдущего примера, обе константы после копирования представляют ссылки на разные объекты, и изменения одного из них никак не затронет другой объект.

Тем не менее если объекты содержат вложенные объекты, то эти вложенные объекты при копировании опять же по сути будут представлять ссылки на один и тот же объект:

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

Сравнение объектов

Сравним два объекта с помощью стандартных операций сравнения и эквивалентности:

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

Оба оператора в данном случае возвратят значение false, то есть объекты не равны. Причем даже если значения свойств объектов будет одинаковым, то мы все равно в обоих случаях получим false

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

Однако, что будет, если обе константы (переменных) хранят ссылку на один и тот же объект:

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

В этом случае в обоих случаях мы получим true, поскольку значения обоих констант равны, так как по сути это одно и то же значение.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850