Jak sprawdzić, czy obiekt jest pusty w JavaScript: vanilla i Lodash

Jak sprawdzić, czy obiekt jest pusty w JavaScript: vanilla i Lodash

Oto krótki fragment kodu, który sprawdza, czy obiekt jest pusty. W nowszych przeglądarkach wystarczy czysty JavaScript i nowe „Object.keys”. W starszych zainstaluj bibliotekę Lodash i skorzystaj z metody „isEmpty”.

javascript
const empty = {};

/* -------------------------
  Vanilla JS dla nowszych przeglądarek
----------------------------*/
Object.keys(empty).length === 0 && empty.constructor === Object
// true

/* -------------------------
  Lodash dla starszych przeglądarek
----------------------------*/
_.isEmpty(empty)
// true

Czym jest vanilla JavaScript?

Vanilla JavaScript to nie jest nowy framework ani nowa biblioteka. To po prostu zwykły JavaScript, bez pomocy Lodasha czy jQuery.

A. Sprawdzanie pustego obiektu w nowszych przeglądarkach

Do sprawdzenia, czy obiekt jest pusty, możemy wykorzystać wbudowaną funkcję Object.keys.

javascript
const empty = {};

Object.keys(empty).length === 0 && empty.constructor === Object;

Po co dodatkowe sprawdzenie constructor?

Pewnie zastanawiasz się, po co nam empty.constructor. Chodzi o puste instancje obiektów tworzone konstruktorem. W JavaScripcie mamy 9 wbudowanych konstruktorów.

javascript
new Object();

new String();
new Number();
new Boolean();
new Array();
new RegExp();
new Function();
new Date();

Pusty obiekt można więc utworzyć przez new Object(). Uwaga: NIGDY nie twórz obiektu za pomocą konstruktora. To zła praktyka, zobacz przewodnik stylu Airbnb i ESLint.

javascript
const obj = new Object();

Object.keys(obj).length === 0; // true

Samo Object.keys zwraca true, kiedy obiekt jest pusty ✅. Ale co się stanie, gdy utworzymy nową instancję obiektu jednym z pozostałych konstruktorów?

javascript
function badEmptyCheck(value) {
  return Object.keys(value).length === 0;
}

badEmptyCheck(new String());    // true 
badEmptyCheck(new Number());    // true 
badEmptyCheck(new Boolean());   // true 
badEmptyCheck(new Array());     // true 
badEmptyCheck(new RegExp());    // true 
badEmptyCheck(new Function());  // true 
badEmptyCheck(new Date());      // true 

No i proszę, mamy fałszywe trafienie…

Fałszywe trafienia rozwiązane przez constructor

Naprawmy to, dodając sprawdzenie konstruktora.

javascript
function goodEmptyCheck(value) {
  Object.keys(value).length === 0
    && value.constructor === Object; // constructor
}

goodEmptyCheck(new String());   // false ✅
goodEmptyCheck(new Number());   // false ✅
goodEmptyCheck(new Boolean());  // false ✅
goodEmptyCheck(new Array());    // false ✅
goodEmptyCheck(new RegExp());   // false ✅
goodEmptyCheck(new Function()); // false ✅
goodEmptyCheck(new Date());     // false ✅

Świetnie! Problem rozwiązany.

Test sprawdzenia na innych wartościach

Dobrze, przepuśćmy przez naszą metodę inne wartości i zobaczmy, co z tego wyjdzie.

javascript
function isEmptyObject(value) {
  return Object.keys(value).length === 0 && value.constructor === Object;
}

Na razie wygląda to nieźle: dla wartości, które nie są obiektami, dostajemy false.

javascript
isEmptyObject(100)  // false
isEmptyObject(true) // false
isEmptyObject([])   // false

Ale uwaga, te wartości wywołają błąd.

javascript

goodEmptyCheck(undefined);
goodEmptyCheck(null);

Lepsza obsługa null i undefined

Jeśli nie chcesz, żeby funkcja rzucała TypeError, dorzuć jeszcze jedno sprawdzenie:

javascript
let value;

value // sprawdzanie null i undefined
 && Object.keys(value).length === 0 && value.constructor === Object;

value = null;       // null
value = undefined;  // undefined

Gotowe, żaden wyjątek już nie leci.

B. Sprawdzanie pustego obiektu w starszych przeglądarkach

A jeśli musisz obsłużyć starsze przeglądarki? Masz dwie drogi: zostać przy wersji vanilla albo sięgnąć po bibliotekę.

Pusty obiekt sprawdzony samym JavaScriptem

Klasyczne podejście nie jest równie zwięzłe, ale robi swoje.

javascript
function isObjectEmpty(value) {
  return (
    Object.prototype.toString.call(value) === '[object Object]' &&
    JSON.stringify(value) === '{}'
  );
}

Dla obiektów zwraca true.

javascript
isObjectEmpty({});           // true ✅
isObjectEmpty(new Object()); // true ✅

Doskonale, nie daje się nabrać na obiekty z konstruktorów.

javascript
isObjectEmpty(new String());   // false ✅
isObjectEmpty(new Number());   // false ✅
isObjectEmpty(new Boolean());  // false ✅
isObjectEmpty(new Array());    // false ✅
isObjectEmpty(new RegExp());   // false ✅
isObjectEmpty(new Function()); // false ✅
isObjectEmpty(new Date());     // false ✅

null i undefined też są pokryte. Dostaniesz false zamiast TypeError.

javascript
isObjectEmpty(null);      // false
isObjectEmpty(undefined); // false

Pusty obiekt sprawdzony biblioteką zewnętrzną

Istnieje mnóstwo zewnętrznych bibliotek, które sprawdzą za ciebie pusty obiekt. Większość z nich świetnie radzi sobie ze starymi przeglądarkami.

Lodash

javascript
_.isEmpty({});
// true

Underscore

javascript
_.isEmpty({});
// true

jQuery

javascript
jQuery.isEmptyObject({});
// true

Vanilla kontra biblioteki

Odpowiedź brzmi: to zależy! Jestem zwolennikiem najprostszego rozwiązania, bo nie lubię narzutu zewnętrznej biblioteki. Przy małych aplikacjach zwyczajnie nie chce mi się jej konfigurować. Ale jeśli twoja aplikacja i tak już taką bibliotekę ma, korzystaj z niej śmiało. Znasz swój projekt lepiej niż ktokolwiek inny, więc wybierz to, co pasuje do twojej sytuacji.

JavaScript

Damien Flandrin Web developer od 2010 roku, twórca Gekkode i Email Impact. Każdy artykuł jest sprawdzany na prawdziwym projekcie przed publikacją. Kontakt
Newsletter

Nowe testy, poradniki i projekty, e-mailem.

Powtarzalne testy, wersjonowany kod, datowane wyniki. Nigdy spamu.