Verificar se um objeto está vazio em JavaScript: vanilla e Lodash

Verificar se um objeto está vazio em JavaScript: vanilla e Lodash

Aqui fica um excerto de código para saber se um objeto está vazio ou não. Nos browsers recentes basta-te JavaScript vanilla com o novo «Object.keys». Nos browsers mais antigos, instala a biblioteca Lodash e usa o método «isEmpty».

javascript
const empty = {};

/* -------------------------
  JS vanilla para os browsers recentes
----------------------------*/
Object.keys(empty).length === 0 && empty.constructor === Object
// true

/* -------------------------
  Lodash para os browsers antigos
----------------------------*/
_.isEmpty(empty)
// true

O que é o JavaScript vanilla?

O JavaScript vanilla não é uma framework nova nem uma biblioteca nova. É simplesmente JavaScript puro, escrito sem recorrer a bibliotecas como o Lodash ou o jQuery.

A. Verificar um objeto vazio nos browsers mais recentes

Para saber se um objeto está vazio podemos usar a função nativa Object.keys.

javascript
const empty = {};

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

Porquê uma verificação adicional de constructor?

Talvez te perguntes para que serve o empty.constructor. Serve para cobrir as instâncias de objeto vazias: em JavaScript existem 9 construtores nativos.

javascript
new Object();

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

Podemos então criar um objeto vazio com new Object(). Uma nota: NUNCA deves criar um objeto através do construtor. É considerado uma má prática, vê o guia de estilo da Airbnb e o ESLint.

javascript
const obj = new Object();

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

Só com Object.keys, o resultado é true quando o objeto está vazio ✅. Mas o que acontece quando criamos uma nova instância com os outros construtores?

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 

Ora bolas, aqui está um falso positivo…

Eliminar o falso positivo com constructor

Vamos corrigir isto acrescentando uma verificação do construtor.

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 ✅

Excelente! O problema está resolvido.

Testar a verificação noutros valores

Muito bem, vamos passar o nosso método por outros valores e ver o que obtemos.

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

Para já parece bem: devolve false para tudo o que não é um objeto.

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

Mas atenção! Estes valores provocam um erro.

javascript

goodEmptyCheck(undefined);
goodEmptyCheck(null);

Melhorar a verificação para null e undefined

Se não queres que seja lançado um TypeError, acrescenta uma verificação suplementar:

javascript
let value;

value // verificação de null e undefined
 && Object.keys(value).length === 0 && value.constructor === Object;

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

Perfeito, já não é lançado nenhum erro.

B. Verificar um objeto vazio nos browsers mais antigos

E se precisares de suportar browsers mais antigos? Aí temos duas opções: ficar por uma versão vanilla ou usar uma biblioteca.

Verificar um objeto vazio com JavaScript

A forma clássica não é tão concisa, mas faz o trabalho.

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

Devolve true para os objetos.

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

Boa, não se deixa enganar pelos nossos objetos criados com construtores.

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 ✅

E estamos cobertos para null e undefined: devolve false em vez de lançar um TypeError.

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

Verificar um objeto vazio com bibliotecas externas

Há imensas bibliotecas externas para verificar objetos vazios e a maioria oferece um bom suporte para os browsers antigos.

Lodash

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

Underscore

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

jQuery

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

Vanilla ou bibliotecas?

A resposta é: depende! Sou adepto de ir pelo mais simples sempre que possível, porque não gosto da sobrecarga que uma biblioteca externa traz. Além disso, em aplicações pequenas tenho preguiça de a configurar. Mas se a tua aplicação já tem uma biblioteca externa instalada, usa-a à vontade. Conheces a tua aplicação melhor do que ninguém: escolhe o que se adequa à tua situação.

JavaScript

Damien Flandrin Programador web desde 2010, criador da Gekkode e do Email Impact. Cada artigo é testado num projeto real antes de ser publicado. Contacto
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.