logo

Сравнение содержимого объектов в JavaScript: методы и решения

Быстрый ответ

Простое сравнение можно выполнить при помощи JSON.stringify:

JS
Скопировать код
const isEqual = JSON.stringify(obj1) === JSON.stringify(obj2);

Но для более тщательной проверки потребуется применить рекурсивное сравнение свойств:

JS
Скопировать код
function deepEqual(a, b) {
  if (a === b) return true;
  if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') return false;
  let keysA = Object.keys(a), keysB = Object.keys(b);
  if (keysA.length !== keysB.length) return false;
  for (let key of keysA) {
    if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
  }
  return true;
}

JSON.stringify подойдет для базовых сценариев сравнения, deepEqual же — для всестороннего анализа объектов.

Путь к эффективности – lodash: многофункциональный инструмент разработчика

Функция _.isEqual из библиотеки lodash предлагает эффективное решение для глубинного сравнения объектов:

JS
Скопировать код
const isEqual = require('lodash').isEqual(obj1, obj2);

Она позволяет обеспечить детализированное сравнение объектов, аналогично разбору ДНК.

Независимая разработка: специализированное сравнение объектов

Изредка может возникнуть необходимость определять собственные правила сравнения. В данном случае стоит реализовать свой метод equals(other):

JS
Скопировать код
class MyObject {
  constructor(data) {
    this.data = data;
  }

  equals(other) {
    return deepEqual(this.data, other.data);
  }
}

Решение специфических задач: функции, регулярные выражения, даты, массивы

Некоторые типы объектов требуют особого подхода:

  • Объекты Date: решающим является их числовое представление, а не визуальное обозначение;
  • Функции: из-за своих специфик, часто исключаются из процесса сравнения;
  • Массивы: здесь важно учитывать порядок и значения элементов.
JS
Скопировать код
let equals;
if (obj1 instanceof Date && obj2 instanceof Date) {
  equals = obj1.getTime() === obj2.getTime();
}

equals = Array.isArray(obj1) && Array.isArray(obj2) &&
         obj1.length === obj2.length &&
         obj1.every((value, index) => deepEqual(value, obj2[index]));

Выжимаем максимум из ES6: всегда держите руку на пульсе

Современный JavaScript предлагает множество удобных опций для сокращения кода:

JS
Скопировать код
const deepEqual = (a, b) => {
  if (a === b) return true;
  if (!a || !b || typeof a !== 'object' || typeof b !== 'object') return false;
  let keysA = Object.keys(a), keysB = Object.keys(b);
  return keysA.every(key => keysB.includes(key) && deepEqual(a[key], b[key]));
};

Эскадрилья спасения: lodash для сложных сравнений

В непростых случаях бесценна помощь от lodash. Он великолепно справится со сравнением вложенных объектов и другими сложными задачами:

JS
Скопировать код
const _ = require('lodash');
const isEqual = _.isEqual(obj1, obj2);

Готовность к встрече с неожиданным: обрабатывайте особые случаи

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

  • Даты: Сопоставьте с использованием getTime() или valueOf().
  • Массивы: Сравнивайте, аналогично обычным объектам, на основе значений и порядка элементов.
  • Функции и регулярные выражения: Их сравнение может быть сложным, так что лучше избегать прямого сравнения.

Полезные материалы

  1. Object.is() – JavaScript | MDN — подробное руководство по использованию Object.is() для сравнения.
  2. Сравнение объектов в JavaScript – Stack Overflow — обсуждение разнообразных вариантов сравнения.
  3. Документация Lodash для _.isEqual() — документация по глубинному сравнению объектов с помощью _.isEqual() из Lodash.
  4. Explaining Value vs. Reference in Javascript | by Arnav Aggarwal | codeburst — объяснение разницы между ссылочными и примитивными типами данных в JavaScript.
  5. GitHub – epoberezkin/fast-deep-equal: Самый быстрый способ проверить глубокое равенство — библиотека для быстрой и точной проверки глубокого равенства.
  6. JSON.stringify() – JavaScript | MDN — подробности использования JSON.stringify() и особенности сравнения объектов.