Is object empty?

Javascript

Javascript Problem Overview


What is the fastest way to check if an object is empty or not?

Is there a faster and better way than this:

function count_obj(obj){
	var i = 0;
	for(var key in obj){
		++i;
	}
	
	return i;
}

Javascript Solutions


Solution 1 - Javascript

For ECMAScript5 (not supported in all browsers yet though), you can use:

Object.keys(obj).length === 0

Solution 2 - Javascript

I'm assuming that by empty you mean "has no properties of its own".

// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;

function isEmpty(obj) {

    // null and undefined are "empty"
    if (obj == null) return true;

    // Assume if it has a length property with a non-zero value
    // that that property is correct.
    if (obj.length > 0)    return false;
    if (obj.length === 0)  return true;

    // If it isn't an object at this point
    // it is empty, but it can't be anything *but* empty
    // Is it empty?  Depends on your application.
    if (typeof obj !== "object") return true;

    // Otherwise, does it have any properties of its own?
    // Note that this doesn't handle
    // toString and valueOf enumeration bugs in IE < 9
    for (var key in obj) {
        if (hasOwnProperty.call(obj, key)) return false;
    }

    return true;
}

Examples:

isEmpty(""), // true
isEmpty(33), // true (arguably could be a TypeError)
isEmpty([]), // true
isEmpty({}), // true
isEmpty({length: 0, custom_property: []}), // true

isEmpty("Hello"), // false
isEmpty([1,2,3]), // false
isEmpty({test: 1}), // false
isEmpty({length: 3, custom_property: [1,2,3]}) // false

If you only need to handle ECMAScript5 browsers, you can use Object.getOwnPropertyNames instead of the hasOwnProperty loop:

if (Object.getOwnPropertyNames(obj).length > 0) return false;

This will ensure that even if the object only has non-enumerable properties isEmpty will still give you the correct results.

Solution 3 - Javascript

EDIT: Note that you should probably use ES5 solution instead of this since ES5 support is widespread these days. It still works for jQuery though.


Easy and cross-browser way is by using jQuery.isEmptyObject:

if ($.isEmptyObject(obj))
{
    // do something
}

More: http://api.jquery.com/jQuery.isEmptyObject/

You need jquery though.

Solution 4 - Javascript

Underscore and lodash each have a convenient isEmpty() function, if you don't mind adding an extra library.

_.isEmpty({});

Solution 5 - Javascript

Lets put this baby to bed; 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 surprising)
  • 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;
}

Results under Node:

  • first result: return (Object.keys(obj).length === 0)
  • second result: for (var x in obj) { return false; }...
  • third result: for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
  • forth result: return ('{}' === JSON.stringify(obj))

Testing for Object with 0 keys 0.00018 0.000015 0.000015 0.000324

Testing for Object with 1 keys 0.000346 0.000458 0.000577 0.000657

Testing for Object with 2 keys 0.000375 0.00046 0.000565 0.000773

Testing for Object with 3 keys 0.000406 0.000476 0.000577 0.000904

Testing for Object with 4 keys 0.000435 0.000487 0.000589 0.001031

Testing for Object with 5 keys 0.000465 0.000501 0.000604 0.001148

Testing for Object with 6 keys 0.000492 0.000511 0.000618 0.001269

Testing for Object with 7 keys 0.000528 0.000527 0.000637 0.00138

Testing for Object with 8 keys 0.000565 0.000538 0.000647 0.00159

Testing for Object with 100 keys 0.003718 0.00243 0.002535 0.01381

Testing for Object with 1000 keys 0.0337 0.0193 0.0194 0.1337

Note that if your typical use case tests a non empty object with few keys, and rarely do you get to test empty objects or objects with 10 or more keys, consider the Object.keys(obj).length option. - otherwise go with the more generic (for... in...) implementation.

Note that Firefox seem to have a faster support for Object.keys(obj).length and Object.getOwnPropertyNames(obj).length, making it a better choice for any non empty Object, but still when it comes to empty objects, the (for...in...) is simply 10 times faster.

My 2 cents is that Object.keys(obj).length is a poor idea since it creates an object of keys just to count how many keys are inside, than destroys it! In order to create that object he needs to loop overt the keys... so why use it and not the (for... in...) option :)

var a = {};

function timeit(func,count) {
   if (!count) count = 100000;
   var start = Date.now();
   for (i=0;i<count;i++) func();
   var end = Date.now();
   var duration = end - start;
   console.log(duration/count)
}

function isEmpty1() {
    return (Object.keys(a).length === 0)
}
function isEmpty2() {
    for (x in a) { return false; }
    return true;
}
function isEmpty3() {
    for (x in a) { if (a.hasOwnProperty(x))  return false; }
    return true;
}
function isEmpty4() {
    return ('{}' === JSON.stringify(a))
}


for (var j=0;j<10;j++) {
   a = {}
   for (var i=0;i<j;i++) a[i] = i;
   console.log('Testing for Object with '+Object.keys(a).length+' keys')
   timeit(isEmpty1);
   timeit(isEmpty2);
   timeit(isEmpty3);
   timeit(isEmpty4);
}

a = {}
for (var i=0;i<100;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4, 10000);

a = {}
for (var i=0;i<1000;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1,10000);
timeit(isEmpty2,10000);
timeit(isEmpty3,10000);
timeit(isEmpty4,10000);

Solution 6 - Javascript

Elegant way - use keys

var myEmptyObj = {};
var myFullObj = {"key":"value"};
console.log(Object.keys(myEmptyObj).length); //0
console.log(Object.keys(myFullObj).length); //1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

Solution 7 - Javascript

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

Solution 8 - Javascript

var x= {}
var y= {x:'hi'}
console.log(Object.keys(x).length===0)
console.log(Object.keys(y).length===0)

true
false

http://jsfiddle.net/j7ona6hz/1/

Solution 9 - Javascript

Surprised to see so many weak answers on such a basic JS question... The top answer is no good too for these reasons:

  1. it generates a global variable
  2. returns true on undefined
  3. uses for...in which is extremely slow by itself
  4. function inside for...in is useless - return false without hasOwnProperty magic will work fine

In fact there's a simpler solution:

function isEmpty(value) {
    return Boolean(value && typeof value === 'object') && !Object.keys(value).length;
}

Solution 10 - Javascript

https://lodash.com/docs#isEmpty comes in pretty handy:

_.isEmpty({})   // true
_.isEmpty()     // true
_.isEmpty(null) // true
_.isEmpty("")   // true

Solution 11 - Javascript

How bad is this?

function(obj){
    for(var key in obj){
        return false; // not empty
    }

    return true; // empty
}

Solution 12 - Javascript

No need for a library.

function(){ //must be within a function
 var obj = {}; //the object to test

 for(var isNotEmpty in obj) //will loop through once if there is a property of some sort, then
    return alert('not empty')//what ever you are trying to do once

 return alert('empty'); //nope obj was empty do this instead;
}

Solution 13 - Javascript

It might be a bit hacky. You can try this.

if (JSON.stringify(data).length === 2) {
   // Do something
}

Not sure if there is any disadvantage of this method.

Solution 14 - Javascript

fast onliner for 'dictionary'-objects:

function isEmptyDict(d){for (var k in d) return false; return true}

Solution 15 - Javascript

You can write a fallback if Array.isArray and Object.getOwnPropertyNames is not available

XX.isEmpty = function(a){
    if(Array.isArray(a)){
        return (a.length==0);
    }
    if(!a){
        return true;
    }
    if(a instanceof Object){
        
        if(a instanceof Date){
            return false;
        }

        if(Object.getOwnPropertyNames(a).length == 0){
            return true;
        }
    }
    return false;
}

Solution 16 - Javascript

Imagine you have the objects below:

var obj1= {};
var obj2= {test: "test"};

Don't forget we can NOT use === sign for testing an object equality as they get inheritance, so If you using ECMA 5 and upper version of javascript, the answer is easy, you can use the function below:

function isEmpty(obj) {
   //check if it's an Obj first
   var isObj = obj !== null 
   && typeof obj === 'object' 
   && Object.prototype.toString.call(obj) === '[object Object]';

   if (isObj) {
       for (var o in obj) {
           if (obj.hasOwnProperty(o)) {
               return false;
               break;
           }
       }
       return true;
   } else {
       console.error("isEmpty function only accept an Object");
   }
}

so the result as below:

isEmpty(obj1); //this returns true
isEmpty(obj2); //this returns false
isEmpty([]); // log in console: isEmpty function only accept an Object

Solution 17 - Javascript

funtion isEmpty(o,i)
{
    for(i in o)
    {
        return!1
    }
    return!0
}

Solution 18 - Javascript

May be you can use this decision:

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

Solution 19 - Javascript

here's a good way to do it

function isEmpty(obj) {
  if (Array.isArray(obj)) {
    return obj.length === 0;
  } else if (typeof obj === 'object') {
    for (var i in obj) {
      return false;
    }
    return true;
  } else {
    return !obj;
  }
}

Solution 20 - Javascript

var hasOwnProperty = Object.prototype.hasOwnProperty;
function isArray(a) {
    return Object.prototype.toString.call(a) === '[object Array]'
}
function isObject(a) {
    return Object.prototype.toString.call(a) === '[object Object]'
}
function isEmpty(a) {
    if (null == a || "" == a)return!0;
    if ("number" == typeof a || "string" == typeof a)return!1;
    var b = !0;
    if (isArray(a)) {
        if (!a.length)return!0;
        for (var c = 0; c < a.length; c++)isEmpty(a[c]) || (b = !1);
        return b
    }
    if (isObject(a)) {
        for (var d in a)hasOwnProperty.call(a, d) && (isEmpty(a[d]) || (b = !1));
        return b
    }
    return!0
}

Solution 21 - Javascript

I modified Sean Vieira's code to suit my needs. null and undefined don't count as object at all, and numbers, boolean values and empty strings return false.

'use strict';

// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;

var isObjectEmpty = function(obj) {
    // null and undefined are not empty
    if (obj == null) return false;
    if(obj === false) return false;
    if(obj === true) return false;
    if(obj === "") return false;

    if(typeof obj === "number") {
        return false;
    }   
    
    // Assume if it has a length property with a non-zero value
    // that that property is correct.
    if (obj.length > 0)    return false;
    if (obj.length === 0)  return true;

    // Otherwise, does it have any properties of its own?
    // Note that this doesn't handle
    // toString and valueOf enumeration bugs in IE < 9
    for (var key in obj) {
        if (hasOwnProperty.call(obj, key)) return false;
    }
    
    
    
    return true;
};

exports.isObjectEmpty = isObjectEmpty;

Solution 22 - Javascript

here my solution

function isEmpty(value) {
	if(Object.prototype.toString.call(value) === '[object Array]') {
		return value.length == 0;
	} else if(value != null && typeof value === 'object') {
		return Object.getOwnPropertyNames(value).length  == 0;
	} else {
	    return !(value || (value === 0));
	}
}

Chears

Solution 23 - Javascript

if (Object.getOwnPropertyNames(obj1).length > 0)
{
 alert('obj1 is empty!');
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionclarkkView Question on Stackoverflow
Solution 1 - JavascriptJakobView Answer on Stackoverflow
Solution 2 - JavascriptSean VieiraView Answer on Stackoverflow
Solution 3 - JavascriptjohndodoView Answer on Stackoverflow
Solution 4 - JavascriptBrad KochView Answer on Stackoverflow
Solution 5 - JavascriptdavidhadasView Answer on Stackoverflow
Solution 6 - JavascriptAlexey BushnevView Answer on Stackoverflow
Solution 7 - JavascriptŠime VidasView Answer on Stackoverflow
Solution 8 - JavascriptToolkitView Answer on Stackoverflow
Solution 9 - Javascriptmike.shestakovView Answer on Stackoverflow
Solution 10 - JavascriptPaweł RychlikView Answer on Stackoverflow
Solution 11 - JavascriptKarmaView Answer on Stackoverflow
Solution 12 - JavascriptAaronView Answer on Stackoverflow
Solution 13 - JavascriptKieve ChuaView Answer on Stackoverflow
Solution 14 - JavascriptRemiView Answer on Stackoverflow
Solution 15 - JavascriptAndreas DyballaView Answer on Stackoverflow
Solution 16 - JavascriptAlirezaView Answer on Stackoverflow
Solution 17 - JavascriptmgtttView Answer on Stackoverflow
Solution 18 - JavascriptSergey GerasimenkoView Answer on Stackoverflow
Solution 19 - Javascriptlink0047View Answer on Stackoverflow
Solution 20 - JavascriptTengizView Answer on Stackoverflow
Solution 21 - JavascriptFoxglove AmberheartView Answer on Stackoverflow
Solution 22 - JavascriptVladimir GordienkoView Answer on Stackoverflow
Solution 23 - JavascriptGimhanView Answer on Stackoverflow