How do I test for an empty JavaScript object?

ID : 102

viewed : 194

Tags : javascriptjavascript-objectsjavascript

Top 5 Answer for How do I test for an empty JavaScript object?

vote vote

98

ECMA 5+:

// because Object.keys(new Date()).length === 0; // we have to do some additional check obj // 👈 null and undefined check && Object.keys(obj).length === 0 && Object.getPrototypeOf(obj) === Object.prototype 

Note, though, that this creates an unnecessary array (the return value of keys).

Pre-ECMA 5:

function isEmpty(obj) {   for(var prop in obj) {     if(Object.prototype.hasOwnProperty.call(obj, prop)) {       return false;     }   }    return JSON.stringify(obj) === JSON.stringify({}); } 

jQuery:

jQuery.isEmptyObject({}); // true 

lodash:

_.isEmpty({}); // true 

Underscore:

_.isEmpty({}); // true 

Hoek

Hoek.deepEqual({}, {}); // true 

ExtJS

Ext.Object.isEmpty({}); // true 

AngularJS (version 1)

angular.equals({}, {}); // true 

Ramda

R.isEmpty({}); // true 
vote vote

85

If ECMAScript 5 support is available, you can use Object.keys():

function isEmpty(obj) {     return Object.keys(obj).length === 0; } 

For ES3 and older, there's no easy way to do this. You'll have to loop over the properties explicitly:

function isEmpty(obj) {     for(var prop in obj) {         if(obj.hasOwnProperty(prop))             return false;     }      return true; } 
vote vote

70

For those of you who have the same problem but use jQuery, you can use jQuery.isEmptyObject.

vote vote

69

Performance

Today 2020.01.17, I performed tests on macOS High Sierra 10.13.6 on Chrome v79.0, Safari v13.0.4, and Firefox v72.0; for the chosen solutions.

Conclusions

  • Solutions based on for-in (A, J, L, M) are fastest
  • Solutions based on JSON.stringify (B, K) are slow
  • Surprisingly, the solution based on Object (N) is also slow

enter image description here

Details

There are 15 solutions presented in the snippet below. If you want to run a performance test on your machine, click HERE. This link was updated 2021.07.08, but tests originally were performed here - and results in the table above came from there (but now it looks like that service no longer works).

var log = (s, f) => console.log(`${s} --> {}:${f({})}  {k:2}:${f({ k: 2 })}`);  function A(obj) {   for (var i in obj) return false;   return true; }  function B(obj) {   return JSON.stringify(obj) === "{}"; }  function C(obj) {   return Object.keys(obj).length === 0; }  function D(obj) {   return Object.entries(obj).length === 0; }  function E(obj) {   return Object.getOwnPropertyNames(obj).length === 0; }  function F(obj) {   return Object.keys(obj).length === 0 && obj.constructor === Object; }  function G(obj) {   return typeof obj === "undefined" || !Boolean(Object.keys(obj)[0]); }  function H(obj) {   return Object.entries(obj).length === 0 && obj.constructor === Object; }  function I(obj) {   return Object.values(obj).every((val) => typeof val === "undefined"); }  function J(obj) {   for (const key in obj) {     if (hasOwnProperty.call(obj, key)) {       return false;     }   }   return true; }  function K(obj) {   for (var prop in obj) {     if (obj.hasOwnProperty(prop)) {       return false;     }   }   return JSON.stringify(obj) === JSON.stringify({}); }  function L(obj) {   for (var prop in obj) {     if (obj.hasOwnProperty(prop)) return false;   }   return true; }  function M(obj) {   for (var k in obj) {     if (obj.hasOwnProperty(k)) {       return false;     }   }   return true; }  function N(obj) {   return (     Object.getOwnPropertyNames(obj).length === 0 &&     Object.getOwnPropertySymbols(obj).length === 0 &&     Object.getPrototypeOf(obj) === Object.prototype   ); }  function O(obj) {   return !(Object.getOwnPropertyNames !== undefined     ? Object.getOwnPropertyNames(obj).length !== 0     : (function () {         for (var key in obj) break;         return key !== null && key !== undefined;       })()); }  log("A", A); log("B", B); log("C", C); log("D", D); log("E", E); log("F", F); log("G", G); log("H", H); log("I", I); log("J", J); log("K", K); log("L", L); log("M", M); log("N", N); log("O", O);

enter image description here

vote vote

59

You can use Underscore.js.

_.isEmpty({}); // true 

Top 3 video Explaining How do I test for an empty JavaScript object?

Related QUESTION?