By falmp


2009-03-25 01:39:45 8 Comments

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

var a = {};

How can I check whether that's the case?

30 comments

@Kamil Kiełczewski 2020-01-17 12:53:28

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.

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

@Tarandeep Singh 2019-11-15 18:06:32

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.

@Eksapsy 2019-11-27 15:38:11

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.

@Ashikur Rahman 2019-11-15 14:12:26

    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.

@davidhadas 2015-12-28 10:40:59

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?

@yankee 2019-11-25 10:43:35

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?

@Роман Татаринов 2019-10-23 15:29:04

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

@kiranvj 2012-06-08 08:04:07

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

@iman 2013-09-03 04:40:19

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)

@kiranvj 2013-09-03 06:31:47

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

@Alireza 2019-10-18 09:43:38

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.

@Anthony D'Amato 2019-05-23 08:07:56

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

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

@João Pimentel Ferreira 2019-04-19 17:31:46

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

@FranzHuber23 2019-10-25 09:18:33

I really like this solution.

@Adam Zerner 2015-08-20 01:32:52

ECMA 7+:

// because Object.entries(new Date()).length === 0;
// we have to do some additional check
Object.entries(obj).length === 0 && obj.constructor === Object

ECMA 5+:

// because Object.keys(new Date()).length === 0;
// we have to do some additional check
Object.keys(obj).length === 0 && obj.constructor === Object

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

@James Dunne 2015-11-06 13:47:41

The Object.keys(...).length method does indeed check that the object is empty, but the return value of 0 is not exclusive to empty objects {}; it also returns 0 for [],"",0,1,function(){}, and I'm sure there are even more examples.

@Adesh M 2015-11-26 07:52:55

We'll prefer var data = {}; Object.keys(data).length; although data = {"a": []} returns 1 which sounds correct. Best while working with REST calls, where REST response can be handled on serverside otherwise go with data = {"success": "lorem ipsum"} or data = {"error": "lorem ipsum"}.

@davidhadas 2015-12-28 10:32:40

The Object.keys({}).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.

@Mikhail 2016-02-09 11:21:38

Here is performance test between jQuery and underscore jsperf.com/isempty-vs-isemptyobject/6

@cjbarth 2016-03-01 16:34:38

Object.keys(new Date()).length === 0; so this answer can be misleading.

@Vivien Adnot 2016-04-12 08:10:28

@Adam Zerner can you explain why do you write return true && JSON.stringify(obj) === JSON.stringify({}); instead of just JSON.stringify(obj) === JSON.stringify({}); ?

@Adam Zerner 2016-04-12 15:45:46

@VivienAdnot To make sure that the input is actually an object, as opposed to a string or something. Without that, if the input is a string, it wouldn't enter the for in loop and would return true, which is wrong because a string isn't an empty object.

@Vivien Adnot 2016-04-13 07:56:32

@Adam Zerner Ok I understand thanks. So with this method, if you send a string in parameter you will receive false as result. Do you think the best solution is this or throwing an exception and receiving it in a try / catch block ?

@Adam Zerner 2016-04-13 14:40:52

Good point. Try-catch does seem more appropriate to me, but I'm not sure, and I was just aggregating others' answers here and the other answer didn't take that approach.

@John Nelson 2016-04-15 12:22:03

Instead of stringifying things you can also take advantage of this fact: (new Date()).constructor === Date, or conversely, ({}).constructor === Object.

@TheZver 2016-05-03 11:56:16

ExtJS: Ext.Object.isEmpty({})

@Jeremy A. West 2016-10-11 14:28:46

angular.equals({}, {});

@Agamemnus 2017-01-02 20:00:01

Is there any disadvantage in using == 0, as .length always returns a number?

@Erik Pukinskis 2017-07-31 19:15:04

What's the purpose of the JSON stringify at the end? Why not just return true?

@Jesse 2018-04-09 09:22:20

Object.keys() doesn't check non-enumerable properties, or symbols. You need to use Object.getOwnPropertyNames() and Object.getOwnPropertySymbols() instead. Also, Object.getPrototypeOf() is the correct way to get an object's prototype. obj.constructor can be easily forged. Example: function Foo() {} Foo.prototype.constructor = Object; (new Foo()).constructor === Object // true.

@Shasak 2018-06-06 15:43:41

the second solution it will also work with empty Arrays.

@Adriano Resende 2018-10-01 19:31:06

Code more simple possible: !!Object.keys(obj).length

@Alireza Mirian 2018-10-23 07:03:48

jQuery.isEmptyObject(new Date()); // true be wary of it.

@doup 2019-01-07 11:59:45

Beware with angular: angular.equals({ $foo: 'bar' }, {}) === true…

@Dalibor 2019-02-01 10:06:41

I tested for cases for loops of million iterations repeated test 10 times, and here are results of consecutive solutions: 1) ECMA 7+: 101 - 146 ms; 2) ECMA 5+ 20 - 37 ms; 3) classic solution: 638 - 669 ms; 4) jQuery: 20 - 32 ms; so the absolute winners are ECMA5 (preferably) and jQuery (optional, don't embed jQuery in your Angular project just because of that)

@Drenai 2019-02-07 17:12:05

@Dalibor You're not comparing like with like there. The ECMA 7/5+ examples are testing against new Date. jQuery skips this test, and fails with jQuery.isEmptyObject(new Date())

@Dalibor 2019-02-13 08:43:05

OK, so we can conclude that ECMA 5 is the winner :)

@DBrown 2019-03-02 04:08:58

The length checks can omit the strict equal and length value, since 0 will act as false, and any positive number will act as true. This was mentioned above with a double not operator, but this is a redundant practice when working with integers. i.e. [].length // 0 => false in condition, [1].length // => 1 true in condition, ![].length // 0 => true with not

@João Pimentel Ferreira 2019-04-30 20:20:29

the Pre-ECMA 5 function does not work with isEmpty([]). You may want to amend accordingly: stackoverflow.com/a/55765589/1243247

@Eliseo d'Annunzio 2019-06-05 05:57:23

There's a Pre-ECMA 5 method I've used: JSON.stringify(searchParams)!="{}" That works rather well... Are there any exceptions where that wouldn't work?

@Nic Scozzaro 2019-09-20 02:46:11

There are many reasons why JS is great, but to me this is a great example of JS sucking. It such a basic, fundamental task (checking for an empty object) and there's no native elegant solution...

@Marc_Alx 2019-10-25 14:55:21

For dojo use lang.isEmpty where lang is dojo/_base/lang

@Petroff 2019-11-04 11:06:45

To optimize a little bit, you can first check for obj.constructor === Object and then Object.keys(obj).length

@Tarandeep Singh 2019-11-15 17:58:04

@Petroff I absolutely agree with you. But even this is not failsafe, if obj is undefined or null, the code breaks at runtime. The better solution would be toString.call(ps) === "[object Object]" && Object.keys(obj).length === 0

@user7331530 2019-11-18 21:48:05

What is this addition check obj.constructor === Object doing? In which scenario, first condition would be false Object.entries(obj).length === 0 so that it would check second condition?

@ncesar 2019-12-18 12:30:47

Awesome ES7 solution :) Thanks!

@Jplus2 2019-03-21 01:56:41

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.

@ahmadalibaloch 2014-05-15 12:51:14

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

@Soren 2014-06-29 01:31:41

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.

@Tudor Morar 2018-09-11 10:35:16

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

typeof obj !== "undefined" && Boolean(Object.keys(obj)[0])

@Jimmy Obonyo Abor 2018-09-25 01:36:01

what if the first key returns false value ? the result will be false which is incorrect .

@Tudor Morar 2018-09-25 10:03:42

I have tested for that. Can you give a working example?

@Mrinmoy 2018-12-04 23:16:36

this is short and concise, but will result in runtime error if the Object is undefined

@Vikrant 2018-12-29 09:11:28

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

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

@faintsignal 2019-01-11 21:05:49

Is there any benefit to using this over Object.keys or Object.values?

@Vikrant 2019-01-13 05:23:52

@faintsignal using those are perfectly fine. I just added entries as did not find it in the comments.

@Jonathan 2018-08-14 21:49:51

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

@Imran Ahmad 2018-08-09 19:13:31

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

@wizebin 2018-11-15 04:36:20

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()

@GibboK 2017-03-29 10:42:36

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

@Dmitry Sheiko 2018-06-27 11:24:01

It's weird I do not find here comparison by values (maybe missed among so many solutions). I would like to cover the case where object is considered empty if all its values are undefined:

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

isObjectEmpty({ foo: undefined, bar: undefined }): // true
isObjectEmpty({ foo: false, bar: null }): // false

Thus, we can extend, let's say, options object only when sub-options provided

function onSubmit({ fullPage, width, height }) {
const baseOptions = { fullPage },
      clip = { width, height },
      options = isObjectEmpty( clip ) ? baseOptions : { ...baseOptions, clip };
//...
}

@Jesse 2018-04-09 09:37:41

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

@Igor Kokotko 2017-11-08 11:06:17

Try Destructuring

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

@gman 2018-01-31 14:28:02

did you actually try this? Put anything in a and it still says empty

@Ashutosh Ranjan 2017-06-30 10:11:11

You could check for the count of the Object keys:

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

@Alejandro Vales 2017-10-13 09:21:08

Why would you add a comment for an answer that was already given and give a worse answer? stackoverflow.com/a/32108184/4229159 and it's the 1st answer from April

@StefansArya 2018-10-09 23:57:16

How if I have a very big object and do that on each loop just to see if the object was empty?

@Jonathan Petitcolas 2013-01-31 10:55:58

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

@mpemburn 2014-05-14 16:10:12

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)

@Dan Dascalescu 2018-11-18 12:47:56

This doesn't add anything to Christoph's answer from 2009.

@Slava Fomin II 2014-05-21 13:55:06

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!

@user663031 2014-09-03 13:24:54

This fails for a null object.

@Slava Fomin II 2014-09-04 12:32:34

Hi @torazaburo! Thanks for taking a notice! I've updated all sources with correct implementation.

@davidhadas 2015-12-28 10:34:25

The Object.keys({}).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.

@cjbarth 2016-03-01 16:35:54

Object.keys(new Date()).length === 0; so this answer can be misleading.

@DiegoAraujo 2017-03-15 13:32:58

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

@mjwrazor 2017-06-01 15:10:14

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).

@Baggz 2011-03-22 20:35:44

You can use Underscore.js.

_.isEmpty({}); // true

@tfmontague 2014-07-23 23:38:52

Or you could use lodash is empty (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.

@Nahn 2014-09-22 16:47:21

It's different if you want to use JS on the backend with Node.js. Few people will want to use jQuery (a front-end library used mostly for DOM manipulations) on the backend.

@rw-nandemo 2014-10-11 21:11:44

@tfmontague underscore is very common on node apps, nearly as ubiquitous as jQ is on client-side. I already had underscore required but didn't realize it had this function

@demisx 2015-02-11 01:44:29

Underscore is being replaced with lodash. Use that instead.

@mentat 2016-01-21 23:04:05

Just be careful with Date types, isEmpty always return true for Date, see github.com/jashkenas/underscore/issues/445

@Bartłomiej Zalewski 2016-08-02 09:45:55

So the answer including jQuery (the one above) has 50 downvotes, this answer including underscore just one downvote. Where is the justice?

@pmont 2017-09-01 18:31:39

@Barth : jQuery is bloated, not modular, and was designed in a time of direct DOM manipulation. jQuery slows page loads significantly, has version compatibility problems when different libs depend on different versions of jQuery, etc. lodash addresses those issues. Modern web development eschews direct DOM manipulation in favor of higher levels of abstraction.

@synthet1c 2015-11-23 12:30:35

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 2015-12-20 12:04:09

@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.

@dgo 2015-12-20 14:23:08

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

@Slavik Meltser 2015-06-10 11:39:32

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! :-)

@cwadding 2015-06-05 17:16:28

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.

@Anish Nair 2014-09-22 05:38:27

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

@Pedro Montoto García 2014-12-18 16:13:07

Will fail for objects with circular references as JSON.stringify specifically throws an exception for them.

@KthProg 2015-01-28 21:18:48

@PedroMontotoGarcía Ok and how will an empty object have a circular reference?

@Pedro Montoto García 2015-01-29 10:31:50

If the object is not empty (and it should work for them too).

@cwadding 2015-06-05 17:19:39

This seems to have been already mentioned by @Ateszki and is one of the slowest ways to check whether an object is not empty.

@Anish Nair 2015-06-06 10:34:03

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.

@davidhadas 2015-12-28 10:33:28

This is a very slow option - I suggest to use the (for...in) option instead

@Dan Dascalescu 2018-11-18 12:50:12

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.

@Ateszki 2013-01-23 20:07:39

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

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

@Vic 2013-09-11 15:05:26

return (JSON.stringify(obj) == '{}')

@user81962 2014-06-11 06:21:05

This is slow and speed matters for this kind of utility. Quick perf test here: jsperf.com/empty-object-test

@davidhadas 2015-12-28 10:33:44

This is a very slow option - I suggest to use the (for...in) option instead

@Felix Kling 2018-06-22 23:27:34

And it doesn't work for objects that contain functions.

@Burak 2019-01-16 17:26:03

It will also throw an error if there's a circular reference in the object. So it's slow, unreliable and can throw errors and break everything else. No reason to use it ever.

Related Questions

Sponsored Content

50 Answered Questions

93 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6261020 View
  • 7818 Score
  • 93 Answer
  • Tags:   javascript arrays

67 Answered Questions

[SOLVED] How do I correctly clone a JavaScript object?

42 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

37 Answered Questions

[SOLVED] How do I return the response from an asynchronous call?

63 Answered Questions

[SOLVED] How can I merge properties of two JavaScript objects dynamically?

39 Answered Questions

[SOLVED] Length of a JavaScript object

68 Answered Questions

[SOLVED] What is the most efficient way to deep clone an object in JavaScript?

86 Answered Questions

[SOLVED] How do JavaScript closures work?

4 Answered Questions

Sponsored Content