Leeg object controleren in JavaScript: Object.keys en Lodash

Leeg object controleren in JavaScript: Object.keys en Lodash

Hier is een stukje code waarmee je controleert of een object leeg is. In recente browsers blijf je gewoon bij vanilla JS en gebruik je het nieuwere “Object.keys”. Voor oudere browsers installeer je de bibliotheek Lodash en gebruik je de methode “isEmpty”.

javascript
const empty = {};

/* -------------------------
  Vanilla JS voor recente browsers
----------------------------*/
Object.keys(empty).length === 0 && empty.constructor === Object
// true

/* -------------------------
  Lodash voor oudere browsers
----------------------------*/
_.isEmpty(empty)
// true

Wat is vanilla JavaScript?

Vanilla JavaScript is geen nieuw framework en geen nieuwe bibliotheek. Het is doodgewoon JavaScript, geschreven zonder hulp van een bibliotheek zoals Lodash of jQuery.

A. Lege objecten controleren in recente browsers

Met de ingebouwde functie Object.keys controleren we of een object leeg is.

javascript
const empty = {};

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

Waarom is er een extra constructor-controle nodig?

Je vraagt je misschien af waarom we empty.constructor erbij halen. Daarmee vangen we lege objectinstanties af. JavaScript kent namelijk 9 ingebouwde constructors.

javascript
new Object();

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

Je kunt dus een leeg object maken met new Object(). Let op: maak een object NOOIT aan via de constructor. Dat geldt als slechte praktijk, zie de Airbnb-styleguide en ESLint.

javascript
const obj = new Object();

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

Met alleen Object.keys krijg je dus true zodra het object leeg is ✅. Maar wat gebeurt er als we een nieuwe objectinstantie maken met die andere constructors?

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 

Helaas, daar is een vals positief…

Valse positieven oplossen met constructor

Dat repareren we met een controle op de constructor.

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 ✅

Mooi! Het probleem is opgelost.

De controle op andere waarden testen

Prima, laten we onze methode op andere waarden loslaten en kijken wat eruit komt.

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

Tot zover goed: voor niet-objecten komt er false uit.

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

Maar pas op! Bij deze waarden loop je tegen een fout aan.

javascript

goodEmptyCheck(undefined);
goodEmptyCheck(null);

De controle verbeteren voor null en undefined

Wil je geen TypeError laten gooien, dan voeg je nog een controle toe:

javascript
let value;

value // controle op null en undefined
 && Object.keys(value).length === 0 && value.constructor === Object;

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

Perfect, er wordt geen enkele fout meer gegooid.

B. Lege objecten controleren in oudere browsers

En als je oudere browsers moet ondersteunen? Dan heb je twee opties. We kunnen bij een vanilla-versie blijven of een bibliotheek inzetten.

Een leeg object controleren met JavaScript

De klassieke aanpak is minder beknopt. Maar hij doet zijn werk.

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

Voor objecten geeft hij true terug.

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

Uitstekend, hij trapt niet in onze constructorobjecten.

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 ✅

En null en undefined zijn afgedekt. Hij geeft false terug en gooit geen TypeError.

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

Een leeg object controleren met externe bibliotheken

Er zijn tientallen externe bibliotheken waarmee je op lege objecten kunt controleren. En de meeste ondersteunen oudere browsers uitstekend.

Lodash

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

Underscore

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

jQuery

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

Vanilla versus bibliotheken

Het antwoord luidt: dat hangt ervan af! Ik houd het zelf graag zo simpel mogelijk, want ik hou niet van de overhead van een externe bibliotheek. Voor kleine applicaties ben ik bovendien te lui om zo’n bibliotheek op te zetten. Maar staat er in jouw applicatie al een externe bibliotheek, gebruik hem dan gerust. Jij kent je applicatie beter dan wie ook. Kies dus wat het beste bij jouw situatie past.

JavaScript

Damien Flandrin Webdeveloper sinds 2010, maker van Gekkode en Email Impact. Elk artikel wordt vóór publicatie getest op een echt project. Contact
Nieuwsbrief

Nieuwe tests, tutorials en projecten, per e-mail.

Reproduceerbare tests, geversioneerde code, gedateerde resultaten. Nooit spam.