По мере того, как я глубже погружался в объектно-ориентированное программирование с использованием JavaScript в Launch School, я обнаружил, что мне постоянно нужно проверять, имеют ли два объекта одинаковые пары ключ/значение.

В Ruby это было легко — Ruby понимал, что вы хотите сравнить записи, которые были в хэше:

Но в JavaScript операторы равенства проверяют, занимают ли два объекта одно и то же место в памяти вашего компьютера. Пример ниже возвращает false вместо true. Черт возьми!

Что мы делаем? JavaScript не дает нам готовое решение, поэтому мы должны создать свое собственное. Нашей функции нужно будет перебрать каждую пару ключ/значение в одном объекте и сравнить их с каждой парой ключ/значение в другом объекте:

Однако у нас есть проблема, что произойдет, если одно из значений в нашем объекте является самим объектом? В приведенном ниже примере ключ cats имеет значение [2] вместо 2. Массивы — это объекты в JavaScript, поэтому, как и раньше, когда наш итератор сравнивает два значения, он возвращает false для всего сравнения, потому что эти два объекта массива не являются одним и тем же местом в памяти компьютера.

Что же нам теперь делать? Рекурсия. Все, что нам нужно сделать, это вставить условие, которое проверяет, является ли текущее значение самим объектом. Если это так, мы можем передать текущее значение и его аналог в объекте сравнения обратно в нашу исходную функцию objectsEqual (строка 6 ниже). Это даст нам глубокую проверку на равенство.

Здорово! Все сделано правильно? Может быть. Последнее, что вы должны задать себе, это вопрос о том, имеет ли значение порядок вставки при сравнении объектов. Например, a и b ниже имеют одинаковые пары ключ/значение, но в другом порядке. Наша текущая функция сказала бы, что эти два одинаковы:

В большинстве случаев порядок, вероятно, не имеет значения… но что, если порядок вставки имеет значение?

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

Например, это:

Становится так:

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

Как и раньше, мы все еще используем рекурсию (в строке 11 в приведенном выше примере), если мы сталкиваемся со значением, которое само является объектом.

Эта проверка порядка является проблемой, только если ключи являются строками. В JavaScript, если ключ объекта является строкой, они повторяются в порядке вставки. Если ключами являются числа, то порядок итераций будет по возрастанию. Если есть сочетание строк и чисел, то числа идут первыми в порядке возрастания, а строки идут следующими в порядке вставки.

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