[javascript] How do I test for an empty JavaScript object?

After an AJAX request, sometimes my application may return an empty object, like:

var a = {};

How can I check whether that's the case?

This question is related to javascript javascript-objects

The answer is


This is what I came up with, to tell if there are any non-null values in the object.

function isEmpty(obj: Object): Boolean {
    for (const prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            if (obj[prop] instanceof Object) {
                const rtn = this.isEmpty(obj[prop]);
                if (rtn === false) {
                  return false;
                }
            } else if (obj[prop] || obj[prop] === false) {
                return false;
            }
        }
    }
    return true;
}

The correct answer is:

const isEmptyObject = obj =>
  Object.getOwnPropertyNames(obj).length === 0 &&
  Object.getOwnPropertySymbols(obj).length === 0 &&
  Object.getPrototypeOf(obj) === Object.prototype;

This checks that:

  • The object has no own properties (regardless of enumerability).
  • The object has no own property symbols.
  • The object's prototype is exactly Object.prototype.

In other words, the object is indistinguishable from one created with {}.


In addition to Thevs answer:

var o = {};
alert($.toJSON(o)=='{}'); // true

var o = {a:1};
alert($.toJSON(o)=='{}'); // false

it's jquery + jquery.json


Mostly what you want to know is, if the object has properties before using it. So instead of asking isEmpty and then always check the negation like if(!isEmpty(obj)) you can just test if the object is not null and has properties instead

export function hasProperties(obj): boolean {
  return obj && obj.constructor === Object && Object.keys(obj).length >= 1;
}


you can use this simple code that did not use jQuery or other libraries

var a=({});

//check is an empty object
if(JSON.stringify(a)=='{}') {
    alert('it is empty');
} else {
    alert('it is not empty');
}

JSON class and it's functions (parse and stringify) are very usefull but has some problems with IE7 that you can fix it with this simple code http://www.json.org/js.html.

Other Simple Way (simplest Way) :
you can use this way without using jQuery or JSON object.

var a=({});

function isEmptyObject(obj) {
    if(typeof obj!='object') {
        //it is not object, so is not empty
        return false;
    } else {
        var x,i=0;
        for(x in obj) {
            i++;
        }
        if(i>0) {
            //this object has some properties or methods
            return false;
        } else {
            //this object has not any property or method
            return true;
        }
    }
}

alert(isEmptyObject(a));    //true is alerted

As per the ES2017 specification on Object.entries(), the check is simple using any modern browser--

Object.entries({}).length === 0

I just ran into a similar situation. I didn't want to use JQuery, and wanted to do this using pure Javascript.

And what I did was, used the following condition, and it worked for me.

var obj = {};
if(JSON.stringify(obj) === '{}') { //This will check if the object is empty
   //Code here..
}

For not equal to, use this : JSON.stringify(obj) !== '{}'

Check out this JSFiddle


Best way that I found:

function isEmpty(obj)
{
    if (!obj)
    {
        return true;
    }

    if (!(typeof(obj) === 'number') && !Object.keys(obj).length)
    {
        return true;
    }

    return false;
}

Works for:

    t1: {} -> true
    t2: {0:1} -: false
    t3: [] -> true
    t4: [2] -> false
    t5: null -> true
    t6: undefined -> true
    t7: "" -> true
    t8: "a" -> false
    t9: 0 -> true
    t10: 1 -> false

Performance

Today 2020.01.17 I perform tests on MacOs HighSierra 10.13.6 on Chrome v79.0, Safari v13.0.4 and Firefox v72.0, for chosen solutions.

Conclusions

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

enter image description here

Details

Below in snippet are presented 15 solutions. If you want to run performance test on your machine click HERE.

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

enter image description here


Using Object.keys(obj).length (as suggested above for ECMA 5+) is 10 times slower for empty objects! keep with the old school (for...in) option.

Tested under Node, Chrome, Firefox and IE 9, it becomes evident that for most use cases:

  • (for...in...) is the fastest option to use!
  • Object.keys(obj).length is 10 times slower for empty objects
  • JSON.stringify(obj).length is always the slowest (not suprising)
  • Object.getOwnPropertyNames(obj).length takes longer than Object.keys(obj).length can be much longer on some systems.

Bottom line performance wise, use:

function isEmpty(obj) { 
   for (var x in obj) { return false; }
   return true;
}

or

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

See detailed testing results and test code at Is object empty?


Pure Vanilla Javascript, and full backward compatibility

_x000D_
_x000D_
function isObjectDefined (Obj) {_x000D_
  if (Obj === null || typeof Obj !== 'object' ||_x000D_
    Object.prototype.toString.call(Obj) === '[object Array]') {_x000D_
    return false_x000D_
  } else {_x000D_
    for (var prop in Obj) {_x000D_
      if (Obj.hasOwnProperty(prop)) {_x000D_
        return true_x000D_
      }_x000D_
    }_x000D_
    return JSON.stringify(Obj) !== JSON.stringify({})_x000D_
  }_x000D_
}_x000D_
_x000D_
console.log(isObjectDefined()) // false_x000D_
console.log(isObjectDefined('')) // false_x000D_
console.log(isObjectDefined(1)) // false_x000D_
console.log(isObjectDefined('string')) // false_x000D_
console.log(isObjectDefined(NaN)) // false_x000D_
console.log(isObjectDefined(null)) // false_x000D_
console.log(isObjectDefined({})) // false_x000D_
console.log(isObjectDefined([])) // false_x000D_
console.log(isObjectDefined({a: ''})) // true
_x000D_
_x000D_
_x000D_


isEmpty for value any type

/* eslint-disable no-nested-ternary */

const isEmpty = value => {
  switch (typeof value) {
    case 'undefined':
      return true;
    case 'object':
      return value === null
        ? true
        : Array.isArray(value)
        ? !value.length
        : Object.entries(value).length === 0 && value.constructor === Object;
    case 'string':
      return !value.length;
    default:
      return false;
  }
};

You could check for the count of the Object keys:

if (Object.keys(a).length > 0) {
    // not empty
}

I know this doesn't answer 100% your question, but I have faced similar issues before and here's how I use to solve them:

I have an API that may return an empty object. Because I know what fields to expect from the API, I only check if any of the required fields are present or not.

For example:

API returns {} or {agentID: '1234' (required), address: '1234 lane' (opt),...}. In my calling function, I'll only check

if(response.data && response.data.agentID) { 
  do something with my agentID 
} else { 
  is empty response
}

This way I don't need to use those expensive methods to check if an object is empty. The object will be empty for my calling function if it doesn't have the agentID field.


Best one-liner solution I could find (updated):

_x000D_
_x000D_
isEmpty = obj => !Object.values(obj).filter(e => typeof e !== 'undefined').length;

console.log(isEmpty({}))                                        // true
console.log(isEmpty({a: undefined, b: undefined}))              // true
console.log(isEmpty({a: undefined, b: void 1024, c: void 0}))   // true

console.log(isEmpty({a: [undefined, undefined]}))               // false
console.log(isEmpty({a: 1}))                                    // false
console.log(isEmpty({a: ''}))                                   // false
console.log(isEmpty({a: null, b: undefined}))                   // false
_x000D_
_x000D_
_x000D_


We can check with vanilla js with handling null or undefined check also as follows,

_x000D_
_x000D_
function isEmptyObject(obj) {
  return !!obj && Object.keys(obj).length === 0 && obj.constructor === Object;
}

//tests

isEmptyObject(new Boolean());  // false 
isEmptyObject(new Array());    // false 
isEmptyObject(new RegExp());   // false 
isEmptyObject(new String());   // false 
isEmptyObject(new Number());   // false 
isEmptyObject(new Function()); // false 
isEmptyObject(new Date());     // false
isEmptyObject(null);          // false
isEmptyObject(undefined);     // false
isEmptyObject({});            // true
_x000D_
_x000D_
_x000D_


A simpler solution: var a = {};
Case a is empty: !Object.keys(a).length returns true.


Perfect and failsafe solution

I think the first accepted solution works in most cases but is not Failsafe.

The better and failsafe solution will be.

function isEmptyObject() { 
  return toString.call(obj) === "[object Object]" 
  && Object.keys(obj).length === 0;
}

or in ES6/7

const isEmptyObject = () => toString.call(obj) === "[object Object]" 
  && Object.keys(obj).length === 0;

With this approach if the obj is set to undefined or null, the code does not break. and return null.


To really accept ONLY {}, the best way to do it in Javascript using Lodash is:

_.isEmpty(value) && _.isPlainObject(value)

My take:

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

var a = {
  a: 1,
  b: 2
}
var b = {}

console.log(isEmpty(a)); // false
console.log(isEmpty(b)); // true
_x000D_
_x000D_
_x000D_

Just, I don't think all browsers implement Object.keys() currently.


Meanwhile we can have one function that checks for all 'empties' like null, undefined, '', ' ', {}, [].

_x000D_
_x000D_
var isEmpty = function(data) {
  if (typeof(data) === 'object') {
    if (JSON.stringify(data) === '{}' || JSON.stringify(data) === '[]') {
      return true;
    } else if (!data) {
      return true;
    }
    return false;
  } else if (typeof(data) === 'string') {
    if (!data.trim()) {
      return true;
    }
    return false;
  } else if (typeof(data) === 'undefined') {
    return true;
  } else {
    return false;
  }
}

//Use cases and results.

console.log(isEmpty()); // true
console.log(isEmpty(null)); // true
console.log(isEmpty('')); // true
console.log(isEmpty('  ')); // true
console.log(isEmpty(undefined)); // true
console.log(isEmpty({})); // true
console.log(isEmpty([])); // true
console.log(isEmpty(0)); // false
console.log(isEmpty('Hey')); // false
_x000D_
_x000D_
_x000D_


    isEmpty = function(obj) {
      if (obj == null) return true;
      if (obj.constructor.name == "Array" || obj.constructor.name == "String") return obj.length === 0;
      for (var key in obj) if (isEmpty(obj[key])) return true;
      return false;
    }

This will check the emptiness of String, Array or Object (Maps).

Usage :

var a = {"a":"xxx","b":[1],"c":{"c_a":""}}
isEmpty(a); // true, because a.c.c_a is empty.
isEmpty("I am a String"); //false

Try Destructuring

const a = {};
const { b } = a;
const emptryOrNot = (b) ? 'not Empty' : 'empty';
console.log(emptryOrNot)

function isEmpty(obj) {
  for(var i in obj) { return false; }
  return true;
}

Under the hood all empty check methods in all libraries use object keys checking logic. Its an odd way to make it understandable, which you can put in a method, Described here.

for(key in obj){
   //your work here.
 break;
}

Which has evolved in ES5, now put simply you can check the object's keys length, using Object.Keys method which takes your object as it's parameter:

if(Object.keys(obj).length > 0){
 //do your work here
}

Or if you are using Lodash (you must be) then.

 _.isEmpty(obj) //==true or false

That's similar way of how it gets checked in lodash source for object :

const isEmpty = value => {
  for (const key in value) {
    if (hasOwnProperty.call(value, key)) {
      return false
    }
  }
  return true;
}

But there are many other ways to do that.


Here is a fast, simple, function:

function isEmptyFunction () {
  for (const i in this) return false
  return true
}

Implemented as a getter:

Object.defineProperty(Object.prototype, 'isEmpty', { get: isEmptyFunction })

console.log({}.isEmpty) // true

Implemented as a separate function:

const isEmpty = Function.prototype.call.bind(isEmptyFunction)

console.log(isEmpty({})) // true

I would go for checking if it has at least one key. That would suffice to tell me that it's not empty.

Boolean(Object.keys(obj || {})[0]) // obj || {} checks for undefined

I liked this one I came up with, with the help of some other answers here. Thought I'd share it.

_x000D_
_x000D_
Object.defineProperty(Object.prototype, 'isEmpty', {
    get() {
        for(var p in this) {
            if (this.hasOwnProperty(p)) {return false}
        }
        return true;
    }
});


let users = {};
let colors = {primary: 'red'};
let sizes = {sm: 100, md: 200, lg: 300};

console.log(
'\nusers =', users,
'\nusers.isEmpty ==> ' + users.isEmpty,
'\n\n-------------\n',
'\ncolors =', colors,
'\ncolors.isEmpty ==> ' + colors.isEmpty,
'\n\n-------------\n',
'\nsizes =', sizes,
'\nsizes.isEmpty ==> ' + sizes.isEmpty,
'\n',
''
);
_x000D_
_x000D_
_x000D_


export function isObjectEmpty(obj) {
  return (
    Object.keys(obj).length === 0 &&
    Object.getOwnPropertySymbols(obj).length === 0 &&
    obj.constructor === Object
  );
}

This include checking for objects containing symbol properties.

Object.keys does not retrieve symbol properties.


  1. Just a workaround. Can your server generate some special property in case of no data?

    For example:

    var a = {empty:true};
    

    Then you can easily check it in your AJAX callback code.

  2. Another way to check it:

    if (a.toSource() === "({})")  // then 'a' is empty
    

EDIT: If you use any JSON library (f.e. JSON.js) then you may try JSON.encode() function and test the result against empty value string.


    let jsObject = JSON.parse(JSON.stringify(obj), (key, value) => {
                if (value === null ||
                    value === '' ||
                    (value.constructor === Object && Object.entries(value).length === 0) ||
                    (value.constructor === Array && value.length === 0)) {
                    return undefined
                }
                return value
            })

This will filter out all the invalid fields recursively.


As of jQuery 1.4 isEmptyObject() method checks both properties on the object itself and properties inherited from prototypes (in that it doesn't use hasOwnProperty). The argument should always be a plain JavaScript Object as other types of object (DOM elements, primitive strings/numbers, host objects) may not give consistent results across browsers. To determine if an object is a plain JavaScript object, use $.isPlainObject().

jQuery.isPlainObject({}) // true

jQuery.isPlainObject( "test" ) // false

Jquery api


The new Way to check value is if(Object.entries(this.props.myarticle).length===0){ }

here myarticles is object


Sugar.JS provides extended objects for this purpose. The code is clean and simple:

Make an extended object:

a = Object.extended({})

Check it's size:

a.size()

You can use Underscore.js.

_.isEmpty({}); // true

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


There is a simple way if you are on a newer browser. Object.keys(obj).length == 0


2021 - solution

What you need is Object.entries(obj).length. It's not good to touch in native prototype.

You can just create your own function and use it as you want. In my case I have a folder called utils where I have a module definition like this:

utils/isEmpty.js

export default (obj) => !Object.entries(obj).length

someFileToUse.js

import isEmpty from '~/utils/isEmpty.js'

const obj1 = {};
const obj2 = {somekey: "someValue"};

console.log(isEmpty(obj1)) 
// -> true

console.log(isEmpty(obj2)) 
// -> false

Caveat! Beware of JSON's limitiations.

javascript:
  obj={  f:function(){}  };
  alert( "Beware!! obj is NOT empty!\n\nobj = {  f:function(){}  }" + 
               "\n\nJSON.stringify( obj )\n\nreturns\n\n" +
                        JSON.stringify( obj ) );

displays

    Beware!! obj is NOT empty!

    obj = {  f:function(){}  }

    JSON.stringify( obj )

    returns

    {}

How about using JSON.stringify? It is almost available in all modern browsers.

function isEmptyObject(obj){
    return JSON.stringify(obj) === '{}';
}

This one line code helps with fallback to older browsers too.

var a = {}; //if empty returns false
(Object.getOwnPropertyNames ? Object.getOwnPropertyNames(a).length !== 0 : (function(){ for(var key in a) break; return !!key })()) //Returns False

var a = {b:2}; //if not empty returns true
(Object.getOwnPropertyNames ? Object.getOwnPropertyNames(a).length !== 0 : (function(){ for(var key in a) break; return !!key })()) //Returns true

Object.getOwnPropertyNames is implemented in ECMA-5. the above line works in older browsers with a fallback function.


Another quick solution is checking the length property of Object.keys, Object.entries or Object.values

Knowledge article: Follow this SO post for detailed difference between Object.keys Vs Object.getOwnPropertyNames


I am using this.

function isObjectEmpty(object) {
  var isEmpty = true;
  for (keys in object) {
     isEmpty = false;
     break; // exiting since we found that the object is not empty
  }
  return isEmpty;
}

Eg:

var myObject = {}; // Object is empty
var isEmpty  = isObjectEmpty(myObject); // will return true;

// populating the object
myObject = {"name":"John Smith","Address":"Kochi, Kerala"}; 

// check if the object is empty
isEmpty  = isObjectEmpty(myObject); // will return false;

from here

Update

OR

you can use the jQuery implementation of isEmptyObject

function isEmptyObject(obj) {
  var name;
  for (name in obj) {
    return false;
  }
  return true;
}

You can define you own object prototype, just before its usage or at the beginning of your code.

The definition should look like this:

_x000D_
_x000D_
Object.prototype.hasOwnProperties = function()_x000D_
{ _x000D_
  for (var k in this)_x000D_
  { _x000D_
    if ( this.hasOwnProperty(k) )_x000D_
    { _x000D_
      return true;_x000D_
    } _x000D_
  }_x000D_
  return false;_x000D_
}
_x000D_
_x000D_
_x000D_

Here is a usage example:

_x000D_
_x000D_
var a = {};_x000D_
_x000D_
while ( a.status !== "finished" )_x000D_
{  _x000D_
  if ( status === "processing" )_x000D_
  {_x000D_
    a.status = "finished";  _x000D_
  }_x000D_
  _x000D_
  if ( status === "starting" )_x000D_
  {_x000D_
    a.status = "processing";  _x000D_
  }_x000D_
  _x000D_
  if ( !a.hasOwnProperties() )_x000D_
  {_x000D_
    a.status = "starting";_x000D_
  }_x000D_
}
_x000D_
_x000D_
_x000D_

Enjoy! :-)


The following example show how to test if a JavaScript object is empty, if by empty we means has no own properties to it.

The script works on ES6.

_x000D_
_x000D_
const isEmpty = (obj) => {_x000D_
    if (obj === null ||_x000D_
        obj === undefined ||_x000D_
        Array.isArray(obj) ||_x000D_
        typeof obj !== 'object'_x000D_
    ) {_x000D_
        return true;_x000D_
    }_x000D_
    return Object.getOwnPropertyNames(obj).length === 0;_x000D_
};_x000D_
console.clear();_x000D_
console.log('-----');_x000D_
console.log(isEmpty(''));           // true_x000D_
console.log(isEmpty(33));           // true_x000D_
console.log(isEmpty([]));           // true_x000D_
console.log(isEmpty({}));           // true_x000D_
console.log(isEmpty({ length: 0, custom_property: [] })); // false_x000D_
console.log('-----');_x000D_
console.log(isEmpty('Hello'));      // true_x000D_
console.log(isEmpty([1, 2, 3]));    // true_x000D_
console.log(isEmpty({ test: 1 }));  // false_x000D_
console.log(isEmpty({ length: 3, custom_property: [1, 2, 3] })); // false_x000D_
console.log('-----');_x000D_
console.log(isEmpty(new Date()));   // true_x000D_
console.log(isEmpty(Infinity));     // true_x000D_
console.log(isEmpty(null));         // true_x000D_
console.log(isEmpty(undefined));    // true
_x000D_
_x000D_
_x000D_


I can't believe after two years of programming js it never clicked that empty objects and array's aren't falsey, the weirdest thing is it never caught me out.

this will return true if the input is falsey by default or if it's an empty object or array. the inverse is the trueish function

http://codepen.io/synthet1c/pen/pjmoWL

function falsish( obj ){
    if( (typeof obj === 'number' && obj > 0) || obj === true ){
        return false;
    }
    return !!obj
        ? !Object.keys( obj ).length
        : true;
}

function trueish( obj ){
    return !falsish( obj );
}

falsish({})           //=> true
falsish({foo:'bar'})  //=> false
falsish([])           //=> true
falsish(['foo'])      //=> false
falsish(false)        //=> true
falsish(true)         //=> false
// the rest are on codepen

If jQuery and the web browser is not available, there is also an isEmpty function in underscore.js.

_.isEmpty({}) // returns true

Additionally, it does not assume the input parameter to be an object. For a list or string or undefined, it will also turn the correct answer.


if(Object.getOwnPropertyNames(obj).length === 0){
  //is empty
}

see http://bencollier.net/2011/04/javascript-is-an-object-empty/


Another alternative is to use is.js (14kB) as opposed to jquery (32kB), lodash (50kB), or underscore (16.4kB). is.js proved to be the fastest library among aforementioned libraries that could be used to determine whether an object is empty.

http://jsperf.com/check-empty-object-using-libraries

Obviously all these libraries are not exactly the same so if you need to easily manipulate the DOM then jquery might still be a good choice or if you need more than just type checking then lodash or underscore might be good. As for is.js, here is the syntax:

var a = {};
is.empty(a); // true
is.empty({"hello": "world"}) // false

Like underscore's and lodash's _.isObject(), this is not exclusively for objects but also applies to arrays and strings.

Under the hood this library is using Object.getOwnPropertyNames which is similar to Object.keys but Object.getOwnPropertyNames is a more thorough since it will return enumerable and non-enumerable properties as described here.

is.empty = function(value) {
    if(is.object(value)){
        var num = Object.getOwnPropertyNames(value).length;
        if(num === 0 || (num === 1 && is.array(value)) || (num === 2 && is.arguments(value))){
            return true;
        }
        return false;
    } else {
        return value === '';
    }
};

If you don't want to bring in a library (which is understandable) and you know that you are only checking objects (not arrays or strings) then the following function should suit your needs.

function isEmptyObject( obj ) {
    return Object.getOwnPropertyNames(obj).length === 0;
}

This is only a bit faster than is.js though just because you aren't checking whether it is an object.


I've created a complete function to determine if object is empty.

It uses Object.keys from ECMAScript 5 (ES5) functionality if possible to achieve the best performance (see compatibility table) and fallbacks to the most compatible approach for older engines (browsers).

Solution

/**
 * Returns true if specified object has no properties,
 * false otherwise.
 *
 * @param {object} object
 * @returns {boolean}
 */
function isObjectEmpty(object)
{
    if ('object' !== typeof object) {
        throw new Error('Object must be specified.');
    }

    if (null === object) {
        return true;
    }

    if ('undefined' !== Object.keys) {
        // Using ECMAScript 5 feature.
        return (0 === Object.keys(object).length);
    } else {
        // Using legacy compatibility mode.
        for (var key in object) {
            if (object.hasOwnProperty(key)) {
                return false;
            }
        }
        return true;
    }
}

Here's the Gist for this code.

And here's the JSFiddle with demonstration and a simple test.

I hope it will help someone. Cheers!


1. Using Object.keys

Object.keys will return an Array, which contains the property names of the object. If the length of the array is 0, then we know that the object is empty.

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

We can also check this using Object.values and Object.entries. This is typically the easiest way to determine if an object is empty.

2. Looping over object properties with for…in

The for…in statement will loop through the enumerable property of object.

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

    return true;
}

In the above code, we will loop through object properties and if an object has at least one property, then it will enter the loop and return false. If the object doesn’t have any properties then it will return true.

#3. Using JSON.stringify If we stringify the object and the result is simply an opening and closing bracket, we know the object is empty.

function isEmptyObject(obj){
    return JSON.stringify(obj) === '{}';
}

4. Using jQuery

jQuery.isEmptyObject(obj); 

5. Using Underscore and Lodash

_.isEmpty(obj);

Resource


It's weird that I haven't encountered a solution that compares the object's values as opposed to the existence of any entry (maybe I missed it among the many given solutions).
I would like to cover the case where an object is considered empty if all its values are undefined:

_x000D_
_x000D_
    const isObjectEmpty = obj => Object.values(obj).every(val => typeof val === "undefined")

    console.log(isObjectEmpty({}))                                 // true
    console.log(isObjectEmpty({ foo: undefined, bar: undefined })) // true
    console.log(isObjectEmpty({ foo: false,     bar: null }))      // false
_x000D_
_x000D_
_x000D_

Example usage

Let's say, for the sake of example, you have a function (paintOnCanvas) that destructs values from its argument (x, y and size). If all of them are undefined, they are to be left out of the resulting set of options. If not they are not, all of them are included.

function paintOnCanvas ({ brush, x, y, size }) {
  const baseOptions = { brush }
  const areaOptions = { x, y, size }
  const options = isObjectEmpty(areaOptions) ? baseOptions : { ...baseOptions, areaOptions }
  // ...
}

jQuery have special function isEmptyObject() for this case:

jQuery.isEmptyObject({}) // true
jQuery.isEmptyObject({ foo: "bar" }) // false

Read more on http://api.jquery.com/jQuery.isEmptyObject/


This is my preferred solution:

var obj = {};
return Object.keys(obj).length; //returns 0 if empty or an integer > 0 if non-empty

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;
}

I was returning an empty JSON response for an AJAX call and in IE8 jQuery.isEmptyObject() was not validating correctly. I added an additional check that seems to catch it properly.

.done(function(data)
{  
    // Parse json response object
    var response = jQuery.parseJSON(data);

    // In IE 8 isEmptyObject doesn't catch the empty response, so adding additional undefined check
    if(jQuery.isEmptyObject(response) || response.length === 0)
    {
        //empty
    }
    else
    {
        //not empty
    }
});

Old question, but just had the issue. Including JQuery is not really a good idea if your only purpose is to check if the object is not empty. Instead, just deep into JQuery's code, and you will get the answer:

function isEmptyObject(obj) {
    var name;
    for (name in obj) {
        if (obj.hasOwnProperty(name)) {
            return false;
        }
    }
    return true;
}