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

Что будет при сравнении идентичных объектов через ==?

1.0 Junior🔥 112 комментариев
#JavaScript Core

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

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

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

Сравнение идентичных объектов через оператор == в JavaScript

При сравнении двух идентичных объектов (содержащих одни и те же свойства с одинаковыми значениями) через оператор нестрогого равенства == в JavaScript всегда возвращается false. Это происходит из-за того, как JavaScript обрабатывает сравнение объектов на уровне спецификации языка.

Принцип работы оператора == с объектами

Оператор == сравнивает объекты не по их содержимому, а по ссылке на облать памяти, где они хранятся. Это фундаментальное поведение для всех сложных типов данных в JS (объекты, массивы, функции и др.).

const obj1 = { name: "Alex" };
const obj2 = { name: "Alex" };

console.log(obj1 == obj2); // false
console.log(obj1 == obj1); // true (сравнивается объект сам с собой)

Почему происходит именно так?

  1. Ссылочная природа объектов
    Каждый литерал объекта {} создаёт новый уникальный объект в памяти, даже если их содержимое идентично. Оператор == проверяет, ссылаются ли обе переменные на один и тот же объект, а не на одинаковые структуры.

  2. Алгоритм сравнения по спецификации ECMAScript
    Согласно стандарту, при сравнении объектов через ==:

    • Если операнды имеют один и тот же тип (оба — объекты), вызывается алгоритм Strict Equality Comparison.
    • Два объекта считаются равными только если они ссылаются на один объект.
  3. Особые случаи сравнения объектов
    При сравнении объекта с примитивом происходит абстрактная операция ToPrimitive, которая может вызвать valueOf() или toString() у объекта:

const obj = { valueOf: () => 42 };

console.log(obj == 42); // true (объект приведётся к числу 42)
console.log(obj == 43); // false

Практические примеры и нюансы

Пример 1: Очевидное сравнение

const a = { id: 1 };
const b = { id: 1 };
const c = a; // c теперь ссылается на тот же объект, что и a

console.log(a == b); // false (разные объекты)
console.log(a == c); // true (одна ссылка)
console.log(a == { id: 1 }); // false (новый литерал)

Пример 2: Сравнение массивов (тоже объекты)

const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];

console.log(arr1 == arr2); // false
console.log(arr1 == "1,2,3"); // true (массив преобразуется в строку)

Пример 3: Особый случай — объекты-обёртки

const str1 = new String("text");
const str2 = new String("text");
const str3 = "text";

console.log(str1 == str2); // false (разные объекты)
console.log(str1 == str3); // true (объект преобразуется в примитив)

Как правильно сравнивать объекты по содержимому?

Для сравнения по структуре данных необходимо:

  1. Ручная проверка свойств
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:
// Использование Lodash
import { isEqual } from 'lodash-es';
console.log(isEqual({ a: { b: 1 } }, { a: { b: 1 } })); // true
  1. JSON.stringify для простых случаев
    Если объект не содержит циклических ссылок и специальных типов:
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // true

Когда сравнение объектов через == может дать true?

  • Сравнение переменной с самой собойobj == obj
  • Сравнение двух ссылок на один объект — после присваивания obj2 = obj1
  • При преобразовании типов — когда объект приводится к примитиву, который равен второму операнду

Вывод

Оператор == для объектов проверяет идентичность ссылок, а не структурное равенство. Для сравнения по содержимому необходимо использовать специальные функции сравнения или современные API типа Object.is() (хотя Object.is() также сравнивает по ссылкам для объектов, но без приведения типов). Понимание этого механизма важно для предотвращения ошибок при работе с коллекциями данных, мемоизации и оптимизации производительности приложений.