> Как проверить, что объект пустой в JavaScript (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: КИТМЕД

Стек: JavaScript

> Пример ответа

Короткий ответ

Проверить пустой объект можно через Object.keys(obj).length === 0 (включает только собственные перечисляемые свойства). Для строгой проверки (включая не перечисляемые и Symbol-ключи) используйте Object.getOwnPropertyNames(obj).length === 0 && Object.getOwnPropertySymbols(obj).length === 0. Для проверки прототипных свойств - JSON.stringify(obj) === '{}'. В современных проектах часто используют lodash.isEmpty().

Подробное объяснение

Понятие "пустой объект" в JavaScript неоднозначно. Объект может быть пустым с точки зрения собственных свойств, но иметь унаследованные от прототипа. Основные подходы:

  1. Object.keys(obj).length === 0 - проверяет только собственные перечисляемые строковые ключи. Самый популярный и быстрый метод.

  2. Object.getOwnPropertyNames(obj) - добавляет не перечисляемые свойства (например, если они были заданы через Object.defineProperty с enumerable: false).

  3. Object.getOwnPropertySymbols(obj) - учитывает Symbol-ключи, которые не попадают в Object.keys().

  4. JSON.stringify(obj) === '{}' - сериализует объект, игнорируя функции и Symbol-ключи. Может быть полезен для проверки "сериализуемой пустоты".

  5. for...in с hasOwnProperty - проверяет и собственные, и унаследованные перечисляемые свойства.

  6. lodash.isEmpty() - учитывает многие edge cases, но добавляет зависимость.

Важно: встроенные объекты (например, new Map()) могут быть "пустыми" по-своему - для них нужны отдельные проверки.

На практике

Выбор метода зависит от контекста:

  • Для обычных литералов объектов ({}) достаточно Object.keys().length === 0.
  • Если объект мог быть создан через Object.create(null) - проверка через Object.keys() всё ещё работает.
  • Для объектов с не перечисляемыми свойствами (например, экземпляры классов) используйте Object.getOwnPropertyNames().
  • В React-приложениях часто проверяют Object.keys(obj).length === 0 для состояния или пропсов.
  • В Node.js middleware - lodash.isEmpty() для единообразия.

Производительность: Object.keys() - O(n) по числу ключей, для пустого объекта это мгновенно. JSON.stringify значительно медленнее из-за сериализации.

Пример кода

JAVASCRIPT
// Базовый случай
const obj1 = {};
console.log(Object.keys(obj1).length === 0); // true
// Не перечисляемое свойство
const obj2 = {};
Object.defineProperty(obj2, 'hidden', { value: 1, enumerable: false });
console.log(Object.keys(obj2).length === 0); // true (не видит hidden)
console.log(Object.getOwnPropertyNames(obj2).length === 0); // false
// Symbol-ключи
const sym = Symbol('test');
const obj3 = { [sym]: 'value' };
console.log(Object.keys(obj3).length === 0); // true
console.log(Object.getOwnPropertySymbols(obj3).length === 0); // false
// Унаследованные свойства
const parent = { inherited: 1 };
const child = Object.create(parent);
console.log(Object.keys(child).length === 0); // true (собственных нет)
console.log(JSON.stringify(child) === '{}'); // true
// Универсальная функция
function isEmptyObject(obj) {
return Object.getOwnPropertyNames(obj).length === 0
&& Object.getOwnPropertySymbols(obj).length === 0;
}

Как отвечать на собеседовании

Начните с самого распространённого способа (Object.keys().length === 0), затем уточните, что он не покрывает все случаи. Покажите понимание различий между собственными и унаследованными свойствами, перечисляемыми и не перечисляемыми. Упомяните Symbol-ключи как современный edge case. Если спросят про производительность - объясните, что Object.keys() работает за O(n) и для пустого объекта это константа. Не забывайте про библиотечные решения (lodash.isEmpty), но подчеркните, что в простых случаях они избыточны.

Что проверяет интервьюер

  • Понимание внутреннего устройства объектов JavaScript (прототипы, дескрипторы свойств).
  • Умение выбирать правильный инструмент под конкретную задачу.
  • Знание современных возможностей (Symbol, Object.getOwnPropertySymbols).
  • Осведомлённость о trade-off между точностью и производительностью.
  • Способность рассуждать о граничных случаях (объекты без прототипа, экземпляры классов).

Типичные ошибки

  • Использование obj === {} - сравнение по ссылке, всегда false.
  • Проверка Object.keys(obj).length === 0 без учёта не перечисляемых свойств.
  • Забывают про Symbol-ключи при работе с современными API (например, Symbol.toStringTag).
  • Путают "пустой объект" с "falsy" - пустой объект всегда truthy.
  • Используют JSON.stringify для объектов с циклическими ссылками (вызовет ошибку).
  • Не учитывают, что Object.keys() на null или undefined выбрасывает TypeError.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью