← Назад к вопросам

Почему при сравнении двух одинаковых объектов возвращается false?

2.0 Middle🔥 81 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Почему сравнение объектов в JavaScript возвращает false

При сравнении двух внешне идентичных объектов в JavaScript операторы == (нестрогое равенство) и === (строгое равенство) возвращают false. Это фундаментальное поведение языка, связанное с тем, как работает ссылочная семантика (reference semantics) при работе с объектами.

Разница между примитивами и объектами

// Примитивы сравниваются по значению
const a = 5;
const b = 5;
console.log(a === b); // true - одинаковые значения

// Объекты сравниваются по ссылке
const obj1 = { name: 'John', age: 30 };
const obj2 = { name: 'John', age: 30 };
console.log(obj1 === obj2); // false - разные ссылки в памяти

Механизм работы сравнения объектов

Строгое равенство (===) для объектов проверяет не содержимое, а ссылки на ячейки памяти. Даже если два объекта имеют идентичную структуру и значения свойств, они занимают разные области памяти, поэтому их ссылки различны.

// Создаем два отдельных объекта
const user1 = { id: 1, name: 'Alice' };
const user2 = { id: 1, name: 'Alice' };

// Они выглядят одинаково, но это разные объекты в памяти
console.log(user1 === user2); // false
console.log(user1 == user2);  // false

Сравнение по ссылке

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

const original = { value: 42 };
const reference = original; // Копируется ссылка, а не объект

console.log(original === reference); // true - одна и та же ссылка
console.log(original === { value: 42 }); // false - другой объект

Глубокое vs поверхностное сравнение

JavaScript не выполняет глубокое сравнение (deep comparison) объектов по умолчанию. Для этого нужны специальные подходы:

1. JSON.stringify() (ограниченный метод)

const objA = { a: 1, b: { c: 2 } };
const objB = { a: 1, b: { c: 2 } };

console.log(JSON.stringify(objA) === JSON.stringify(objB)); // true
// Но есть ограничения: порядок свойств, undefined, функции, циклические ссылки

2. Ручная реализация глубокого сравнения

function deepEqual(obj1, obj2) {
  // Сравнение примитивов и проверка на null
  if (obj1 === obj2) return true;
  if (typeof obj1 !== 'object' || obj1 === null || 
      typeof obj2 !== 'object' || obj2 === null) {
    return false;
  }
  
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  
  if (keys1.length !== keys2.length) return false;
  
  for (const key of keys1) {
    if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {
      return false;
    }
  }
  
  return true;
}

3. Использование библиотек

// Lodash
import _ from 'lodash';
console.log(_.isEqual(obj1, obj2)); // true при идентичной структуре

Особые случаи и нюансы

  • Нестрогое равенство (==) также сравнивает ссылки для объектов
  • Объекты-обертки (String, Number, Boolean) создают новые объекты:
console.log(new String('test') === new String('test')); // false
console.log('test' === 'test'); // true
  • Массивы — это тоже объекты:
console.log([1, 2, 3] === [1, 2, 3]); // false
  • Поверхностное сравнение (shallow comparison) проверяет только первый уровень:
function shallowEqual(obj1, obj2) {
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  
  if (keys1.length !== keys2.length) return false;
  
  return keys1.every(key => obj1[key] === obj2[key]);
}

Практические рекомендации

  1. Для сравнения по значению используйте библиотеки типа Lodash (_.isEqual())
  2. Для простых объектов можно использовать JSON.stringify(), учитывая ограничения
  3. В React для пропсов часто применяется поверхностное сравнение
  4. Для иммутабельных обновлений в Redux создавайте новые объекты при изменениях
  5. При кэшировании (memoization) важно правильно определять равенство объектов

Понимание этого поведения критически важно для эффективной работы с JavaScript, особенно при оптимизации производительности, работе с состоянием приложений и реализации корректной логики сравнения.

Почему при сравнении двух одинаковых объектов возвращается false? | PrepBro