
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”.
const empty = {};
/* -------------------------
Vanilla JS dla nowszych przeglądarek
----------------------------*/
Object.keys(empty).length === 0 && empty.constructor === Object
// true
/* -------------------------
Lodash dla starszych przeglądarek
----------------------------*/
_.isEmpty(empty)
// trueCzym 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.
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.
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.
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?
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.
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.
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.
isEmptyObject(100) // false
isEmptyObject(true) // false
isEmptyObject([]) // false
Ale uwaga, te wartości wywołają błąd.
goodEmptyCheck(undefined);
goodEmptyCheck(null);
Lepsza obsługa null i undefined
Jeśli nie chcesz, żeby funkcja rzucała TypeError, dorzuć jeszcze jedno sprawdzenie:
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.
function isObjectEmpty(value) {
return (
Object.prototype.toString.call(value) === '[object Object]' &&
JSON.stringify(value) === '{}'
);
}
Dla obiektów zwraca true.
isObjectEmpty({}); // true ✅
isObjectEmpty(new Object()); // true ✅
Doskonale, nie daje się nabrać na obiekty z konstruktorów.
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.
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
_.isEmpty({});
// true
Underscore
_.isEmpty({});
// true
jQuery
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.


