В JavaScript нет единственного универсального способа проверки на равенство объектов, так как объекты сравниваются по ссылке, а не по содержанию. Ниже представлены несколько способов проверки на равенство, от простых до сложных, с учетом различных сценариев.
Этот способ проверяет, указывают ли две переменные на один и тот же объект в памяти.
const obj1 = { a: 1 };
const obj2 = obj1;
const obj3 = { a: 1 };
console.log(obj1 === obj2); // true (одинаковые ссылки)
console.log(obj1 === obj3); // false (разные ссылки, даже если содержимое одинаково)✅ Когда использовать: Когда вам нужно знать, ссылаются ли переменные на один и тот же объект.
Простой способ для сравнения объектов с простыми типами данных (строки, числа, булевы значения, массивы, вложенные объекты).
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
const obj3 = { a: 1, b: { c: 3 } };
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // true
console.log(JSON.stringify(obj1) === JSON.stringify(obj3)); // false- Не работает с
undefined,function,Symbol,Date,RegExp,Map,Set. - Порядок ключей в объектах может влиять на результат (хотя в современных JS-движках порядок обычно сохраняется, но это не гарантировано стандартом для всех случаев).
- Не различает
nullиundefinedв некоторых контекстах.
✅ Когда использовать: Для быстрого сравнения простых JSON-подобных объектов в тестировании или отладке.
Самый надежный способ для ручного сравнения объектов с учетом структуры и типов данных.
function deepEqual(obj1, obj2) {
// Проверка на идентичность (включая NaN)
if (obj1 === obj2) return true;
// Проверка на null или не объект
if (obj1 == null || obj2 == null || typeof obj1 !== 'object' || typeof obj2 !== 'object') {
return false;
}
// Сравнение массивов
if (Array.isArray(obj1) !== Array.isArray(obj2)) 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;
}
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
const obj3 = { a: 1, b: { c: 3 } };
console.log(deepEqual(obj1, obj2)); // true
console.log(deepEqual(obj1, obj3)); // false✅ Когда использовать: Когда нужно точное сравнение содержимого объектов, включая вложенные структуры.
Если вы используете Lodash, функция _.isEqual() предоставляет надежное глубокое сравнение.
import _ from 'lodash';
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
const obj3 = { a: 1, b: { c: 3 } };
console.log(_.isEqual(obj1, obj2)); // true
console.log(_.isEqual(obj1, obj3)); // false✅ Когда использовать: В больших проектах, где важна надежность и поддержка сложных типов данных (Date, Map, Set и т.д.).
Если порядок ключей важен, можно использовать Object.keys() для сравнения.
function deepEqualWithKeyOrder(obj1, obj2) {
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
for (let i = 0; i < keys1.length; i++) {
if (keys1[i] !== keys2[i]) return false; // Порядок ключей должен совпадать
if (!deepEqual(obj1[keys1[i]], obj2[keys2[i]])) return false;
}
return true;
}| Способ | Ссылка/Содержимое | Сложность | Поддержка типов |
|---|---|---|---|
=== |
Ссылка | Низкая | Все объекты |
JSON.stringify() |
Содержимое | Низкая | Простые типы (JSON) |
| Рекурсивная функция | Содержимое | Средняя | Настраиваемая |
Lodash _.isEqual() |
Содержимое | Низкая (если библиотека подключена) | Все типы (включая Date, Map, Set) |
- Для быстрых проверок простых объектов используйте
JSON.stringify(). - Для надежного сравнения в производстве используйте Lodash или напишите свою рекурсивную функцию.
- Для проверки идентичности (один ли это объект) используйте
===.