JavaScript | Равенство объектов

JavaScript | Равенство объектов

В чём тут проблема? Посмотрите на такие условия:

{a:"a"} == {a:"a"}
{a:"a"} === {a:"a"}

В обоих случаях мы получим ответ ЛОЖЬ (false), когда сравниваем два объекта.

Объекты не равны - JavaScript
Объекты не равны — JavaScript

Но мы же видим, что объекты полностью идентичны. У них одинаковые КЛЮЧИ и ЗНАЧЕНИЯ. Это наш критерий ОДИНАКОВОСТИ.

Вся проблема в том, что под каждый ключ каждого объекта выделяется участок оперативной памяти компьютера. То есть каждый ключ ссылается на своё место в памяти и с точки зрения языка программирования JavaScript это разные ссылки, а значит и ключи разные. Если ключи разные, то и объекты разные. (логика, примерно, такая).

 

Задача

У нас есть задача о добавлении уникальных объектов в массив. В нашем случае поиск такого объекта в массиве сказал бы, что этот объект уникален — и добавил бы его в массив. Это проблема, от которой мы хотим избавиться.

Посмотрите на такой Набор(Set):

new Set([{a:"a"},{a:"a"},{a:"a"},{a:"a"},{a:"a"}])
Набор из объектов - JavaScript
Набор из объектов — JavaScript

 

А теперь на такой Набор(Set):

new Set(["a", "a", "a", "a", "a"])
Набор из строк - JavaScript
Набор из строк — JavaScript

Чувствуете разницу? То есть JavaScript считает объекты с одинаковыми ключами и значениями РАЗНЫМИ. Но как только мы сравниваем обычные строки, то всё сразу хорошо.

Сравнивать массивы мы тоже не можем, т. к. результат будет аналогично не подходящим:

Массивы не равны - JavaScript
Массивы не равны — JavaScript

Решение

По сути нам тоже нужно сравнивать строки, которые будут получаться из преобразования объекта. Поможет нам в этом объект JSON. Например так:

JSON.stringify(Object.entries({a:"a"}).sort()) == JSON.stringify(Object.entries({a:"a"}).sort())
Сравнение объектов через конструктор JSON - JavaScript
Сравнение объектов через конструктор JSON — JavaScript

Что мы сделали? Давайте по шагам

Шаг 1. Обратились к конструктору Object и у него вызвали метод entries(). В метод entries() мы передали наш объект. Метод entries() вернул нам новый массив в виде пар «ключ/значение» из нашего переданного объекта:

Object.entries({a:"a"})
Object.entries - JavaScript
Object.entries — JavaScript

Шаг 2. Отсортировали элементы массива по возрастанию

Шаг 3. Передали отсортированный массив в метод stringify() конструктора JSON

Шаг 4. Сравнили две версии между собой

 

Другой пример

Возьмём объекты из не сортированных ключей. Сравним их:

{
   0:22,
   1:44,
   5:66,
   100:1000
}

{
   0:22,
   100:1000,
   5:66,
   1:44
}

Команда сравнения объектов:

JSON.stringify(Object.entries({ 0:22, 1:44, 5:66, 100:1000 }).sort()) == JSON.stringify(Object.entries({ 0:22, 100:1000, 5:66, 1:44 }).sort())
Объекты равны, Ключи сортированы - JavaScript
Объекты равны, Ключи сортированы — JavaScript

Получили true. Это значит, что эти два объекта равны друг другу.

 

Информационные ссылки

Объекты JavaScript — https://efim360.ru/javascript-obekty-object/

Стандарт ECMAScriptObject Objectshttps://tc39.es/ecma262/#sec-object-objects