
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».
const empty = {};
/* -------------------------
JS vanilla para os browsers recentes
----------------------------*/
Object.keys(empty).length === 0 && empty.constructor === Object
// true
/* -------------------------
Lodash para os browsers antigos
----------------------------*/
_.isEmpty(empty)
// trueO 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.
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.
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.
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?
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.
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.
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.
isEmptyObject(100) // false
isEmptyObject(true) // false
isEmptyObject([]) // false
Mas atenção! Estes valores provocam um erro.
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:
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.
function isObjectEmpty(value) {
return (
Object.prototype.toString.call(value) === '[object Object]' &&
JSON.stringify(value) === '{}'
);
}
Devolve true para os objetos.
isObjectEmpty({}); // true ✅
isObjectEmpty(new Object()); // true ✅
Boa, não se deixa enganar pelos nossos objetos criados com construtores.
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.
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
_.isEmpty({});
// true
Underscore
_.isEmpty({});
// true
jQuery
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.


