3704

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

var a = {};

How can I check whether that's the case?

Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
falmp
  • 37,429
  • 3
  • 19
  • 18
  • 10
    Do you use JSON.js script? Or any other JSON library. Then you can use JSON.encode() function to convert var to string and then test it. – Thevs Mar 25 '09 at 13:50
  • 7
    Just check for `if (Object.keys(obj).length === 0) { // handle empty obj }` – Gabriel Petersson Jul 22 '20 at 14:27
  • 4
    @GabrielPetersson Please never provide solutions as comments. Your comment is a violation of this Q&A's very clear/simple page design. Resolving advice is to be posted as an answer. Comments under the question should ask the OP for clarification or offer non-resolving insights. https://meta.stackexchange.com/a/296481/352329 – mickmackusa Aug 04 '20 at 05:53

59 Answers59

6389

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 && obj.constructor === Object

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(obj.hasOwnProperty(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
dipenparmar12
  • 1,314
  • 1
  • 11
  • 25
Adam Zerner
  • 12,221
  • 13
  • 62
  • 128
997

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;
}
mikemaccana
  • 81,787
  • 73
  • 317
  • 396
Christoph
  • 149,808
  • 36
  • 172
  • 230
584

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

iota
  • 34,586
  • 7
  • 32
  • 51
  • 45
    HEY! I just spent a few hours debugging IE 8 issues only to find that it was jQuery.isEmptyObject that was causing the problem. It returns true if the object is empty. – MFD3000 Aug 17 '11 at 19:03
  • @MFD3000: Could you explain in detail what you did? Did you feed jQuery.isEmptyObject() with a string? In that case have a look at http://bugs.jquery.com/ticket/7413 and http://api.jquery.com/jQuery.isEmptyObject/. – Erik Töyrä Silfverswärd Sep 16 '11 at 20:13
  • 3
    This won't work if you (or any plugin) modified Object.prototype. – Michał Miszczyszyn Jun 05 '12 at 09:13
  • 173
    Why do you post answer including jQuery if the question is not about jQuery at all? – Eru Oct 01 '12 at 14:10
  • 51
    I know its an old comment, but I wonder your question @MFD3000, because the docu says: returns true, if object is empty (as the name indicates it) – Александр Фишер Dec 12 '12 at 19:44
  • 22
    including jQuery for such a basic task is not what I would call the right answer. It's true that nowadays jQuery is almost ubiquous, but still we shouldn't forget it is built around a very capable language itself. – Pablo Mescher Feb 27 '13 at 17:04
  • note that this works fine for the question asked, {}, but that jQuery.isEmptyObject([]) === true, presumably because an empty list is iterable. – Paul Sanwald May 17 '13 at 16:20
  • 2
    @eru he's psychic, knew that his answer would get the most votes. how'd he do that? –  Aug 13 '13 at 18:27
  • 3
    Note that jQuery.isEmptyObject returns **false** when you feed it an empty jQuery object (as noted on [its API page](http://api.jquery.com/jQuery.isEmptyObject/)). It only works for regular JavaScript objects. – DawnPaladin Oct 01 '14 at 15:40
  • 61
    Typical JS snobbery in these comments. Everyone knows a huge proportion of JavaScript on the web is written on jQuery, so it is perfectly acceptable to provide a solution here for jQuery if it already has a built-in method for testing objects. It's likely that thousands of developers looking for help will find this answer helpful. Nobody said it's the only way to do it. I notice how nobody acts all elitist about the guy who posted a solution to use `underscore.js`... – BadHorsie Jul 07 '15 at 15:35
  • 1
    @BadHorsie that is bm. So each time a question about dates in javascript is asked we should answer with a random function of a date library? And the reason nobody acts 'elitist' about the underscore.js answer is only because he is not the accepted answer. – Tristan Jul 22 '15 at 11:52
  • 15
    @Tristan jQuery is hardly some random library, is it? It's only the most popular JS library of all time, on which millions of sites rely. I don't see the problem with posting both answers so that there is a pure JS solution, and a jQuery solution so developers who are working on jQuery sites know about a quick built-in function. Obviously nobody is suggesting you load the entire jQuery library on your site for the sole purpose of using one small utility function... It's pretty obviously meant to be a solution for people already using jQuery... – BadHorsie Jul 22 '15 at 12:19
334

This is my preferred solution:

var obj = {};
return Object.keys(obj).length; //returns 0 if empty or an integer > 0 if non-empty
dhruvio
  • 3,357
  • 1
  • 8
  • 2
218

You can use Underscore.js.

_.isEmpty({}); // true
Gabriel GM
  • 5,761
  • 2
  • 28
  • 32
Baggz
  • 16,239
  • 4
  • 35
  • 25
  • 22
    Or you could use lodash is empty (http://lodash.com/docs#isEmpty), but how is that any different from using a jQuery solution - you still need to install an additional library. I think a vanilla javascript solution is the intent. – tim-montague Jul 23 '14 at 23:38
168

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

There are 15 solutions presented in the snippet below. If you want to run a performance test on your machine click HERE.

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

If my answer helped you can buy me a coffee

Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
  • a lot of this doesn't make sense because you're basing everything on a return of false and or true. Sometimes programming needs an if statement or a ternary operator. just fyi – Christian Matthew Apr 10 '20 at 07:32
  • 5
    For completeness, I edited your jsperf to test `obj = {a:1,b:2,c:3}` and `for(var i in obj)` is still the fastest https://jsperf.com/object-empty-ch/2 – Madacol Jun 13 '20 at 00:08
123
if(Object.getOwnPropertyNames(obj).length === 0){
  //is empty
}

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

es cologne
  • 2,268
  • 1
  • 15
  • 11
  • 5
    This includes non-enumerable properties, in case you care. –  Sep 03 '14 at 13:33
  • The Object.getOwnPropertyNames({}).length is 10 times slower than the (for...in...) option - I suggest to avoid it as a way to test if an objetc is empty. – davidhadas Dec 28 '15 at 10:35
  • 4
    `Object.getOwnPropertyNames(new Date()).length === 0`; so this answer can be misleading. – cjbarth Mar 01 '16 at 16:37
92

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

function isEmptyObject(obj){
    return JSON.stringify(obj) === '{}';
}
sktguha
  • 355
  • 2
  • 18
Ateszki
  • 2,019
  • 14
  • 11
62

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;
}
peterh
  • 9,698
  • 15
  • 68
  • 87
Jonathan Petitcolas
  • 3,645
  • 3
  • 25
  • 41
  • 5
    This is only useful if some other process hasn't added a prototype to your base object. To make this truly workable, you need to test for obj.hasOwnProperty(name) – mpemburn May 14 '14 at 16:10
61

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

Anish Nair
  • 2,978
  • 26
  • 41
  • 6
    Will fail for objects with circular references as JSON.stringify specifically throws an exception for them. – Pedro Montoto García Dec 18 '14 at 16:13
  • 2
    @PedroMontotoGarcía Ok and how will an empty object have a circular reference? – KthProg Jan 28 '15 at 21:18
  • 9
    If the object is not empty (and it should work for them too). – Pedro Montoto García Jan 29 '15 at 10:31
  • 2
    This seems to have been already mentioned by @Ateszki and is one of the slowest ways to check whether an object is not empty. – cwadding Jun 05 '15 at 17:19
  • Oh yes.. I missed it. I ran into a situation where I wanted to achieve this javascript, and after a bit of thinking I figured out this way. @Ateszki, Even I though the way you did. :-) Btw, there were a lot of answers on this, and so I missed your answer. – Anish Nair Jun 06 '15 at 10:34
  • This is a very slow option - I suggest to use the (for...in) option instead – davidhadas Dec 28 '15 at 10:33
  • As @cwadding said, this is a duplicate answer. No shame in deleting it, because it doesn't help anyone. On the contrary, users don't notice it's a duplicate, and upvote it without seeing the hidden comment by cwadding about the slowness, while that comment is visible in the original answer and has 20+ upvotes. – Dan Dascalescu Nov 18 '18 at 12:50
43

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

download
  • 1,348
  • 11
  • 25
  • 1
    Where does the `keys` property come from? –  Sep 03 '14 at 13:23
  • 2
    It's a [standard method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) in ECMAScript 5.1 – download Sep 04 '14 at 22:41
  • 1
    How can the above comment have 4 upvotes? Yes, `Object.keys` is a standard method but objects do not have a keys property. So this code will report any object as empty except it accidentally happens to have a property named `key` with a value which again as a property named `length` which is not zero. Horrible! – scravy Aug 05 '15 at 14:45
  • `Object.keys(new Date()).length === 0`; so this answer can be misleading. – cjbarth Mar 01 '16 at 16:40
  • 14
    @scravy Object is the class Object. Object has a static method named 'keys' which accepts an object as an argument. This method returns an array of strings where the strings are property names. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys – Sgnl Jan 04 '17 at 20:05
42

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?

tim-montague
  • 12,048
  • 2
  • 50
  • 40
davidhadas
  • 2,123
  • 18
  • 16
  • `Object.keys` is slow, but less code. On a small page, where this is called... maybe 10 times... Will this still be slower considering the additional parsing time of the additional code? – yankee Nov 25 '19 at 10:43
35

You could check for the count of the Object keys:

if (Object.keys(a).length > 0) {
    // not empty
}
danopz
  • 2,999
  • 5
  • 26
  • 36
Ashutosh Ranjan
  • 624
  • 5
  • 10
  • 9
    Why would you add a comment for an answer that was already given and give a worse answer? https://stackoverflow.com/a/32108184/4229159 and it's the 1st answer from **April** – Alejandro Vales Oct 13 '17 at 09:21
  • 1
    How if I have a very big object and do that on each loop just to see if the object was empty? – StefansArya Oct 09 '18 at 23:57
  • This answer doesn't appear to add anything that the accepted answer doesn't already say. – mickmackusa Aug 04 '20 at 06:10
29
  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.

franzlorenzon
  • 5,333
  • 6
  • 31
  • 55
Thevs
  • 3,105
  • 2
  • 19
  • 31
  • 6
    `toSource()` is non-standard and doesn't work in IE or Opera (and potentially other browsers I didn't check) – Christoph Mar 25 '09 at 12:21
  • This is standard in ECMA-262. There are non-standard browsers though. – Thevs Mar 25 '09 at 20:46
  • 4
    @Thevs: perhaps you have a different copy of the current version of ECMA-262, but mine does not list a `toSource` property in section 15.2.4; according to MDC, it was introduced in JS1.3 (i.e. Netscape Navigator 4.06), but it's NOT in ECMA-262, 3rd edition! – Christoph Mar 25 '09 at 22:47
  • @Christoph: How do you think 3 other browsers would implement the same 'non-standard' feature if that wouldn't be a standard? :) – Thevs Mar 26 '09 at 09:20
  • 4
    @Thevs: well, at least 2 important browser vendors didn't implement it, so it's hardly a de-facto-standard, and as it's not in ECMA-262, it's not a real one either... – Christoph Mar 26 '09 at 09:34
  • ...and as for how features get implemented across different browsers without being standard: ever heard of innovation and a thing called copying? It's how the standard was developed ion the first place (JavaScript and JScript predate ECMAScript) – Christoph Mar 26 '09 at 09:35
  • BTW, toSource() is implemented in IE _internally_, but nor exposed to outside. Think why? – Thevs Apr 20 '09 at 20:13
  • There is no such method as toSource() – Peter Aron Zentai Jun 06 '14 at 18:04
  • 4
    Even when it does work, `toSource()` is a horrible way to do this (as is `JSON.encode()`). It needs to build a string representing your entire object to just check if it's empty. There's the overhead of converting things to strings, but moreover it will need to convert a million things if your object has a million properties, while actually just looking at one will let you know that it is not empty. – Jasper Aug 12 '14 at 08:42
  • @Jasper: There is not bigger overhead than checking object in a cycle for key values like in the most popular answer here :) – Thevs Aug 30 '14 at 12:00
  • 4
    @Thevs the overhead is bigger, even if it *might be* (I'm not sure it is under every circumstance) in the same order of magnitude. However, that answer involves returning false as soon as a different property is found which makes the story is different all together... – Jasper Sep 01 '14 at 08:32
25

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!

Slava Fomin II
  • 21,036
  • 19
  • 98
  • 176
25

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

Object.entries({}).length === 0
Vikrant
  • 480
  • 4
  • 9
21

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;
}
ns16
  • 1,014
  • 2
  • 10
  • 19
kiranvj
  • 22,650
  • 5
  • 51
  • 69
  • hi. when you test this function with number or boolean true or false return true and this is not correct result. isObjectEmpty(true). isObjectEmpty(false). isObjectEmpty(1) – iman Sep 03 '13 at 04:40
  • 2
    We are checking whether the object is empty, not if the data type is an object. In your case to check if its an object we need to something like if(typeof a === "object") {...} – kiranvj Sep 03 '13 at 06:31
21

My take:

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

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

CertainPerformance
  • 260,466
  • 31
  • 181
  • 209
NiKo
  • 10,608
  • 5
  • 42
  • 56
  • 2
    `Object.keys(new Date()).length === 0`; so this answer can be misleading. – cjbarth Mar 01 '16 at 16:40
  • 3
    Depends if you consider a date being always "full" despite never exposing keys. But I agree that if that's your plan, adding some supplementary instanceof check for Date constructor is a good option. – NiKo Mar 20 '16 at 11:31
16

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.

const isEmpty = (obj) => {
    if (obj === null ||
        obj === undefined ||
        Array.isArray(obj) ||
        typeof obj !== 'object'
    ) {
        return true;
    }
    return Object.getOwnPropertyNames(obj).length === 0;
};
console.clear();
console.log('-----');
console.log(isEmpty(''));           // true
console.log(isEmpty(33));           // true
console.log(isEmpty([]));           // true
console.log(isEmpty({}));           // true
console.log(isEmpty({ length: 0, custom_property: [] })); // false
console.log('-----');
console.log(isEmpty('Hello'));      // true
console.log(isEmpty([1, 2, 3]));    // true
console.log(isEmpty({ test: 1 }));  // false
console.log(isEmpty({ length: 3, custom_property: [1, 2, 3] })); // false
console.log('-----');
console.log(isEmpty(new Date()));   // true
console.log(isEmpty(Infinity));     // true
console.log(isEmpty(null));         // true
console.log(isEmpty(undefined));    // true
LostMyGlasses
  • 2,614
  • 15
  • 26
GibboK
  • 64,078
  • 128
  • 380
  • 620
16
function isEmpty(obj) {
  for(var i in obj) { return false; }
  return true;
}
Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989
  • 4
    That'll report also true, when, for instance, a JavaScript library extends `Object` with a method through the prototype chain, because that's enumerable and the `for in` statement loops through enumerable properties. – viam0Zah Apr 24 '09 at 13:20
13

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/

13

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
Tudor Morar
  • 2,720
  • 21
  • 20
12

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
ahmadalibaloch
  • 5,289
  • 1
  • 40
  • 55
  • While is is correct as an odd way of making an if-statement -- it will probably confuse somebody who will maintain the code after you. – Soren Jun 29 '14 at 01:31
11


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
iman
  • 5,359
  • 1
  • 17
  • 23
  • `JSON.stringify` solution fails if object contains non-stringifiable properties such as functions or "undefined", although granted that's an edge case. –  Sep 03 '14 at 13:29
11

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
DiegoAraujo
  • 135
  • 1
  • 6
  • 3
    I would say that 0 is not empty since it is actually a number. everything else looks good but the fix is easy. in the first if statement add this. `if (!obj && obj !== 0)`. – mjwrazor Jun 01 '17 at 15:10
9

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.

jichi
  • 5,010
  • 1
  • 28
  • 25
9

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 {}.

Jesse
  • 5,386
  • 3
  • 34
  • 39
9

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

Dohd
  • 173
  • 2
  • 4
8

In addition to Thevs answer:

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

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

it's jquery + jquery.json

starikovs
  • 2,694
  • 1
  • 25
  • 30
8

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

    {}
Ekim
  • 933
  • 1
  • 8
  • 7
7

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

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
CertainPerformance
  • 260,466
  • 31
  • 181
  • 209
Imran Ahmad
  • 5,684
  • 3
  • 32
  • 43
  • 3
    You shouldn't stringify your data in a utility function like this. Imagine if you had an object with 1GB of data stored in it, and decided to run this function on it- you'd stringify the whole object just to check to see if it has anything inside it? Just use `Object.keys()` – wizebin Nov 15 '18 at 04:36
6

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()
mikemaccana
  • 81,787
  • 73
  • 317
  • 396
6

Pure Vanilla Javascript, and full backward compatibility

function isObjectDefined (Obj) {
  if (Obj === null || typeof Obj !== 'object' ||
    Object.prototype.toString.call(Obj) === '[object Array]') {
    return false
  } else {
    for (var prop in Obj) {
      if (Obj.hasOwnProperty(prop)) {
        return true
      }
    }
    return JSON.stringify(Obj) !== JSON.stringify({})
  }
}

console.log(isObjectDefined()) // false
console.log(isObjectDefined('')) // false
console.log(isObjectDefined(1)) // false
console.log(isObjectDefined('string')) // false
console.log(isObjectDefined(NaN)) // false
console.log(isObjectDefined(null)) // false
console.log(isObjectDefined({})) // false
console.log(isObjectDefined([])) // false
console.log(isObjectDefined({a: ''})) // true
João Pimentel Ferreira
  • 9,166
  • 6
  • 52
  • 67
6

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

_.isEmpty(value) && _.isPlainObject(value)
Anthony D'Amato
  • 687
  • 1
  • 5
  • 20
6

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
Fábio BC Souza
  • 674
  • 8
  • 15
5

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

Ericgit
  • 2,624
  • 2
  • 22
  • 34
4

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.

Community
  • 1
  • 1
cwadding
  • 809
  • 8
  • 14
4

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

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
Ran Marciano
  • 1,254
  • 5
  • 7
  • 25
Alex Tudor
  • 65
  • 8
3

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

Nirus
  • 3,078
  • 2
  • 18
  • 42
3
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.

Jplus2
  • 1,578
  • 2
  • 20
  • 38
3

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.

2

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
synthet1c
  • 5,543
  • 2
  • 15
  • 30
  • 1
    @user1167442 The array you have provided is not empty, it's an array containing an empty array, so is not what I would describe as falshish. I'm not sure that it could be handled without adding recursion increasing the complexity of the basic function. – synthet1c Dec 20 '15 at 12:04
  • - I got it. I got here looking for a solution that would handle both scenarios elegantly, so though your code is fine; I was irritated that it didn't solve my problem :). U got up voted for solving the problem you were trying to solve. – dgo Dec 20 '15 at 14:23
2

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:

    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

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 }
  // ...
}
Ran Marciano
  • 1,254
  • 5
  • 7
  • 25
Dmitry Sheiko
  • 1,842
  • 1
  • 21
  • 24
2

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

here myarticles is object

Aakash Handa
  • 716
  • 7
  • 14
2

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

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
ganesh phirke
  • 305
  • 2
  • 11
2

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

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',
''
);
010011100101
  • 1,203
  • 6
  • 18
2

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;
}
Arya
  • 2,140
  • 1
  • 9
  • 27
Ron Jonk
  • 363
  • 2
  • 7
0

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

Mureinik
  • 252,575
  • 45
  • 248
  • 283
chandu
  • 2,198
  • 3
  • 18
  • 35
0

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

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

The definition should look like this:

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

Here is a usage example:

var a = {};

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

Enjoy! :-)

Slavik Meltser
  • 7,008
  • 2
  • 37
  • 37
0

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;
}
Jonathan
  • 71
  • 1
  • 3
0

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.

Alireza
  • 83,698
  • 19
  • 241
  • 152
0

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

Ashikur Rahman
  • 121
  • 3
  • 9
0

You can use lodash library instead of making a plain JS function.

_.isEmpty({}) // true

This will check array and object either they do have values and return boolean.

hardik
  • 19
  • 3
-1

Try Destructuring

const a = {};
const { b } = a;
const emptryOrNot = (b) ? 'not Empty' : 'empty';
console.log(emptryOrNot)
Igor Kokotko
  • 400
  • 3
  • 12
-1

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
Gust van de Wal
  • 4,519
  • 18
  • 39
will Farrell
  • 1,549
  • 1
  • 15
  • 19
  • 4
    Without `Object.hasOwnProperty`, this function will always return `true` (the function is called `isEmpty`, but returns true when it's not empty, by the way...). Also, the function will not invoke itself automatically. Add `()` after `obj.isEmpty`. – Rob W May 07 '12 at 14:01
  • 2
    Also, after just stumbling across this you would probably want to swap the return true/false statements. The function 'isEmpty' should return false once it finds a property, because that means that it is _not_ empty. Semantics, but would probably be a good idea. – Jeff Lambert Jul 05 '12 at 13:59
-2

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.

Tarandeep Singh
  • 1,112
  • 14
  • 15
  • 2
    You are checking if an object is empty with fixed strings and hacks/irregular practices like "toString.call(obj). This is just bad practice and code you dont wanna see in a codebase. There are much better and clean solutions that make sense just by reading them. This does not make sense while reading it, it's a hack. – Eksapsy Nov 27 '19 at 15:38