Avatar ·

Как проверить, пустой ли объект в JavaScript? (простые и надёжные способы)

Всем привет! Я только начал изучать JavaScript и столкнулся с такой задачей: мне нужно понять, пустой ли объект или нет. Например, у меня есть объект `user`, который может быть пустым `{}` или содержать какие-то данные. Я попробовал сравнить его с пустым объектом: ```javascript const obj = {}; if (obj === {}) { console.log('Объект пуст'); } else { console.log('Объект не пуст'); } ``` Но этот код всегда выводит "Объект не пуст", даже когда объект действительно пустой. Я понимаю, что в JavaScript объекты сравниваются по ссылке, а не по содержимому, но как тогда правильно проверить? Ещё я пробовал использовать `obj.length` — но это работает только для массивов, для объектов возвращает `undefined`. Мне нужно проверять объекты, которые приходят с сервера или создаются динамически. Например, после обработки формы я получаю объект с настройками фильтрации, и если он пустой — не отправляю запрос. Подскажите, пожалуйста, какой самый простой и надёжный способ проверить, содержит ли объект хоть одно собственное свойство? Желательно, чтобы решение работало во всех современных браузерах и Node.js. Заранее спасибо! <<>>

Правильный способ проверки пустого объекта

Проблема, с которой вы столкнулись, типична для новичков: оператор === сравнивает объекты по ссылке, а не по содержимому. Даже два пустых объекта {} — это разные объекты в памяти, поэтому сравнение всегда возвращает false. Чтобы проверить, пустой ли объект, нужно смотреть на его собственные перечисляемые свойства.

Метод 1: Object.keys() (рекомендуемый)

Самый простой и читаемый способ — использовать Object.keys(obj), который возвращает массив собственных перечисляемых свойств объекта. Если массив пуст — объект пуст:

const isEmpty = (obj) => Object.keys(obj).length === 0;

// Примеры:
console.log(isEmpty({}));           // true
console.log(isEmpty({a: 1}));       // false
console.log(isEmpty({name: 'John', age: 30})); // false

Этот метод работает во всех современных браузерах и Node.js. Он не учитывает свойства в цепочке прототипов — только то, что принадлежит самому объекту.

Метод 2: Object.getOwnPropertyNames()

Если вам нужно учитывать также неперечисляемые свойства (например, созданные через Object.defineProperty с enumerable: false), используйте Object.getOwnPropertyNames():

const isEmptyStrict = (obj) => Object.getOwnPropertyNames(obj).length === 0;

const obj = {};
Object.defineProperty(obj, 'hidden', {
  value: 42,
  enumerable: false
});

console.log(Object.keys(obj).length);            // 0 (не видит скрытое свойство)
console.log(Object.getOwnPropertyNames(obj).length); // 1 (видит скрытое свойство)

Метод 3: Проверка через for...in с hasOwnProperty

Классический способ, который работает даже в очень старых браузерах:

function isEmpty(obj) {
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      return false;
    }
  }
  return true;
}

Этот метод надёжен, но более многословен. hasOwnProperty отсекает унаследованные свойства из прототипа.

Что выбрать?

  • Для 99% случаев — используйте Object.keys(obj).length === 0. Это современно, читаемо и быстро.
  • Если нужна поддержка очень старых браузеров (IE8-) — используйте for...in с hasOwnProperty.
  • Если есть скрытые свойства — используйте Object.getOwnPropertyNames().

Важное замечание про null и undefined

Все перечисленные методы упадут с ошибкой, если передать null или undefined. Поэтому в реальном коде стоит добавить защиту:

const isEmpty = (obj) => {
  if (obj === null || obj === undefined) {
    throw new Error('Argument must be an object');
  }
  return Object.keys(obj).length === 0;
};

Или, если вы ожидаете, что может прийти null, и хотите считать его "пустым":

const isEmptySafe = (obj) => obj == null || Object.keys(obj).length === 0;

Теперь вы можете смело проверять пустые объекты. Для вашей задачи с формой фильтрации идеально подойдёт Object.keys(obj).length === 0 — просто и надёжно!

<<>>

Альтернативный подход: JSON.stringify

Некоторые разработчики используют сериализацию в JSON для проверки пустоты:

const isEmpty = (obj) => JSON.stringify(obj) === '{}';

console.log(isEmpty({}));           // true
console.log(isEmpty({a: 1}));       // false

Этот метод работает, но имеет существенные недостатки:

  • Медленнее — сериализация целого объекта в строку занимает больше времени, чем получение списка ключей.
  • Не учитывает функции и символы — JSON.stringify игнорирует свойства-функции и символьные ключи. Объект {method: () => {}} будет считаться пустым.
  • Проблемы с циклическими ссылками — если объект содержит ссылку сам на себя, JSON.stringify выбросит ошибку.

Когда это может пригодиться?

Метод JSON.stringify может быть полезен, если вы уже сериализуете объект для отправки на сервер или сохранения в localStorage — тогда вы можете совместить проверку и сериализацию. Но для обычной проверки пустоты лучше использовать Object.keys() — это быстрее, безопаснее и предсказуемее.