«Объект пуст — или нет?» Разбираемся с вечной головной болью JavaScript-разработчика
Представьте: вы пишете приложение, получаете от API ответ, и вам нужно понять — пришли ли данные? Или объект пуст, и пора показывать пользователю заглушку? Или вы обрабатываете форму, и нужно проверить, заполнил ли пользователь хотя бы одно поле? Ситуация до боли знакомая каждому, кто пишет на JavaScript.
Казалось бы, что может быть проще? if (obj === {}) — и дело в шляпе? Увы, нет. В JavaScript два объекта, даже с абсолютно одинаковым содержимым, никогда не будут равны друг другу, если это не один и тот же объект в памяти. Проверка пустого объекта JavaScript — это та задача, которая собрала тысячи просмотров на Stack Overflow и породила целую индустрию решений.
В этой статье мы разберём 5 надёжных способов, как определить, что перед вами пустой объект. От классических до современных, от быстрых до безопасных. Поехали!
Что значит «пустой объект» в JavaScript?
Прежде чем кидаться в код, давайте договоримся о терминах. Пустой объект в JavaScript — это объект, у которого нет собственных перечисляемых свойств. То есть {} — пустой. А вот { name: "Alice" } — уже нет.
Важный нюанс: у любого объекта есть прототип (Object.prototype), а значит, у него есть унаследованные свойства (например, toString, hasOwnProperty). Нас они не интересуют. Мы проверяем только то, что добавили мы сами.
Ещё один подводный камень — null. Если переменная равна null или undefined, то мы даже не можем вызвать у неё методы. Поэтому первым делом всегда проверяем, что объект существует.
Способ 1: Object.keys() — золотой стандарт
Самый популярный и рекомендуемый способ в современном JavaScript. Метод Object.keys() возвращает массив собственных перечисляемых свойств объекта. Если массив пуст — объект пуст.
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
// Примеры использования
console.log(isEmpty({})); // true
console.log(isEmpty({a: 1})); // false
console.log(isEmpty({name: 'John', age: 30})); // false
Почему это работает? Object.keys() игнорирует унаследованные свойства и возвращает только то, что принадлежит самому объекту. Проверка объекта на пустоту с помощью Object.keys() — это чистый, читаемый и быстрый код.
Важно: Этот метод не проверяет, является ли переданное значение объектом. Если передать строку или число, он вернёт пустой массив, и мы ошибочно решим, что объект пуст. Поэтому для надёжности добавляем проверку типа:
function isEmptySafe(obj) {
return obj && typeof obj === 'object' && Object.keys(obj).length === 0;
}
console.log(isEmptySafe('hello')); // false (строка — не объект)
console.log(isEmptySafe(null)); // false
console.log(isEmptySafe({})); // true
Способ 2: JSON.stringify() — неожиданный, но рабочий
Иногда программисты в шутку называют этот способ «костылём», но он работает. Идея проста: сериализовать объект в JSON-строку и сравнить её с '{}'.
function isEmptyJSON(obj) {
return JSON.stringify(obj) === '{}';
}
console.log(isEmptyJSON({})); // true
console.log(isEmptyJSON({key: 'val'})); // false
Почему этот способ не идеален? Во-первых, JSON.stringify() игнорирует функции, undefined и символы. Если у объекта есть свойство со значением undefined, оно просто исчезнет при сериализации, и объект будет признан пустым, хотя на самом деле у него есть ключ.
const obj = { a: undefined };
console.log(isEmptyJSON(obj)); // true — а должно быть false!
Во-вторых, это медленнее, чем Object.keys(). Поэтому проверка пустого объекта javascript через JSON.stringify — это вариант для крайних случаев, когда вы точно знаете, что в объекте нет функций и undefined.
Способ 3: Цикл for...in — дедовский метод
До появления Object.keys() разработчики использовали цикл for...in. Он перебирает все перечисляемые свойства объекта, включая унаследованные. Поэтому приходится добавлять проверку hasOwnProperty().
function isEmptyForIn(obj) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
}
return true;
}
console.log(isEmptyForIn({})); // true
console.log(isEmptyForIn({a: 1})); // false
Этот код надёжен, но громоздок. В современных проектах его используют редко — разве что если нужно поддерживать очень старые браузеры (IE8 и ниже), где Object.keys() не работал. Проверка объекта на пустоту с помощью for in — это скорее исторический экспонат, чем практический инструмент.
Способ 4: Lodash _.isEmpty() — тяжёлая артиллерия
Если вы используете библиотеку Lodash (а она есть во многих проектах), то задача упрощается до одной функции. _.isEmpty() проверяет не только объекты, но и массивы, строки, Map, Set и даже arguments-объект.
// Подключите Lodash: npm install lodash
const _ = require('lodash');
console.log(_.isEmpty({})); // true
console.log(_.isEmpty({a: 1})); // false
console.log(_.isEmpty([])); // true
console.log(_.isEmpty('')); // true
console.log(_.isEmpty(null)); // true — без ошибок!
Главный плюс — универсальность и безопасность. Lodash isempty проверка пустого объекта не упадёт с ошибкой, если передать null или число. Минус — вы тащите в проект целую библиотеку ради одной функции. Хотя современные сборщики (webpack, esbuild) позволяют импортировать только нужные модули.
Способ 5: Reflect.ownKeys() — для самых продвинутых
Метод Reflect.ownKeys() возвращает массив всех собственных ключей объекта, включая не перечисляемые и символы. Это самый полный и строгий способ.
function isEmptyReflect(obj) {
return Reflect.ownKeys(obj).length === 0;
}
const obj = {};
Object.defineProperty(obj, 'hidden', {
value: 42,
enumerable: false // не перечисляемое свойство
});
console.log(isEmptyReflect(obj)); // false — нашлось скрытое свойство
console.log(Object.keys(obj).length === 0); // true — Object.keys() его не видит
Этот метод полезен,