318

Is there any built-in function that can return the length of an object?

For example, I have a = { 'a':1,'b':2,'c':3 } which should return 3. If I use a.length it returns undefined.

It could be a simple loop function, but I'd like to know if there's a built-in function?

There is a related question (Length of a JSON object) - in the chosen answer the user advises to transform object into an array, which is not pretty comfortable for my task.

Community
  • 1
  • 1
Larry Foobar
  • 11,092
  • 15
  • 56
  • 89
  • 2
    Why is it not comfortable for you? – BoltClock Apr 03 '11 at 23:24
  • In that topic is advised to make transformation and there every element is written manually - that's why – Larry Foobar Apr 03 '11 at 23:26
  • 1
    2 Billy Moon, may be I didn't find that topic, because I've search by words "object", but there is "associatve array". Sorry – Larry Foobar Apr 03 '11 at 23:33
  • This should be more canonical: http://stackoverflow.com/questions/126100/how-to-efficiently-count-the-number-of-keys-properties-of-an-object-in-javascript/ but some of the answers are rubbish. Oh well... – Yi Jiang Apr 03 '11 at 23:40

15 Answers15

596

For browsers supporting Object.keys() you can simply do:

Object.keys(a).length;

Otherwise (notably in IE < 9), you can loop through the object yourself with a for (x in y) loop:

var count = 0;
var i;

for (i in a) {
    if (a.hasOwnProperty(i)) {
        count++;
    }
}

The hasOwnProperty is there to make sure that you're only counting properties from the object literal, and not properties it "inherits" from its prototype.

David Tang
  • 92,262
  • 30
  • 167
  • 149
  • 45
    Thanks! BTW, can you add `var i` at the top? It's hurting my eyes. – sinelaw Apr 09 '13 at 19:32
  • 1
    Object.keys(a).length : IE8 doesn't support this and still a large user base use IE8. Therefore, I wouldn't rely on this. – lshettyl Apr 12 '13 at 12:24
  • 14
    You can also add the "var" in the loop: for(var i in a){ – gadlol Nov 15 '13 at 22:51
  • 3
    I thought I'd share a link to the Object.keys and its polyfill as stated by Mozilla: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys#Polyfill – Design by Adrian Aug 07 '14 at 15:57
  • Your 2nd `hasOwnProperty` check with loop approach works in all IE versions?? as i need this because i am having problems when i use length property(it makes everything hang when object is undefined/empty) – dev-m Aug 16 '14 at 22:35
  • 2
    If you wanted to make things simpler (despite some unprofessional syntax), you could simply do `var count=0,i; for (i in a) if (a.hasOwnProperty(i)) count++;` – Conor O'Brien Dec 10 '14 at 21:38
  • +1 the loop alternative for any implementation that don’t support `Object.keys()`. – dakab Jul 14 '16 at 17:45
  • I believe this is the correct answer. I was looking for something that would work in my Nodejs server and this is perfect. – George Miranda Sep 26 '17 at 19:05
81

This should do it:

Object.keys(a).length

However, Object.keys is not supported in IE8 and below, Opera and FF 3.6 and below.

Live demo: http://jsfiddle.net/simevidas/nN84h/

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • Yeah, I thought about this decision too, but then we should write our own keys() function (crossbrowser function I mean) – Larry Foobar Apr 04 '11 at 00:06
  • @Innuendo Yes, but that's something that you would want to do anyway. IE8 is going to stick around for a couple of more years (like until 2016 at least), and implementing JavaScript features (for browsers that don't support them) is a trivial and safe task, so there is no reason not do to it. You wouldn't want to avoid the new ES5 features for the next 5 years just because of IE8 - that would be senseless `:)` – Šime Vidas Apr 04 '11 at 00:13
  • Yea, I've understood. We have to suffer until 2016 (I'm joking `:)`) – Larry Foobar Apr 04 '11 at 00:18
  • In case anyone is wondering, this was the first answer which included `Object.keys` - @DavidTang merely [edited their answer](https://stackoverflow.com/posts/5533226/revisions) years later to include this answer. – Jacksonkr Oct 19 '20 at 16:20
61

Can be done easily with $.map():

var len = $.map(a, function(n, i) { return i; }).length;
VMAtm
  • 27,943
  • 17
  • 79
  • 125
Fazle Rabbi
  • 902
  • 7
  • 4
  • 1
    This works only with jquery 1.6+ as stated in the jQuery.map() documentation: `Prior to jQuery 1.6, $.map() supports traversing arrays only. As of jQuery 1.6 it also traverses objects.` – icramc Dec 28 '12 at 22:46
  • 5
    This is actually worse than using a simple loop and counter because of the added overhead of the callback function. – nullability Feb 19 '13 at 17:35
46

Have you taken a look at underscore.js (http://underscorejs.org/docs/underscore.html)? It's a utility library with a lot of useful methods. There is a collection size method, as well as a toArray method, which may get you what you need.

_.size({one : 1, two : 2, three : 3});
=> 3
Szymon
  • 1,281
  • 1
  • 20
  • 36
Philip Schweiger
  • 2,714
  • 1
  • 18
  • 27
  • 1
    Thanks, I'll look at this library. But really, I do not want to use lots of libraries (I've already use jQuery library) – Larry Foobar Apr 04 '11 at 00:10
  • @Innuendo In case you didn't notice, underscore.js contains the `keys` function which I mentioned in my answer. If you use underscore.js, you can use that `keys` function - in that case, modern browsers will use the built-in `keys` function, and IE8 (and other browsers that don't have a built-in `keys` function) will use the custom function defined by underscore.js. – Šime Vidas Apr 04 '11 at 00:18
  • Ok. I do not like to use many .js files (may be kind of a messy), so I think to merge jquery.js and underscore.js in on file '_jquery.js' for example, and use these libraries together `=)` – Larry Foobar Apr 04 '11 at 00:20
  • 2
    @Innuendo `_jquery.js` - I like that name `:)`. However, I recommend using [Google's CDN for jQuery](https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js). As for underscore, it's still not on Google's CDN yet, but there is [demand for it](http://code.google.com/p/google-ajax-apis/issues/detail?id=528). As for now, I've found underscore [at this CDN](http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js) - it's hosted on Amazon servers so it should be fast and reliable. – Šime Vidas Apr 04 '11 at 00:33
  • @Philip Schweiger. Can you explain me, why is better to use Google's CDN url for libraries? I'm always recommended to do this, but I do not understand why? Also, why there is no CDN url to the latest jquery - I mean version of jQuery IS written in the url – Larry Foobar Apr 04 '11 at 00:36
  • 1
    @Innuendo Because a considerable number of web-sites use Google's CDN for jQuery. That means that the jQuery file is probably already cached inside the browser when the user requests your web-site. In that case, the browser doesn't have to request the jQeury file at all - it uses the cached one. If you want the latest 1.5 jQuery file, you can just remove `.2` from the URL and it will work too. – Šime Vidas Apr 04 '11 at 01:03
  • Now I understand why this is usefull - thank you for explaining – Larry Foobar Apr 04 '11 at 01:05
  • I am using laravel framework and this seems to be working great. I believe the Lodash library is included with laravel's app.js – Maarten Kuijper Aug 20 '17 at 11:53
21

Summarizing all together, here is a universal function (including ie8 support):

var objSize = function(obj) {
    var count = 0;
    
    if (typeof obj == "object") {
    
        if (Object.keys) {
            count = Object.keys(obj).length;
        } else if (window._) {
            count = _.keys(obj).length;
        } else if (window.$) {
            count = $.map(obj, function() { return 1; }).length;
        } else {
            for (var key in obj) if (obj.hasOwnProperty(key)) count++;
        }
        
    }
    
    return count;
};

document.write(objSize({ a: 1, b: 2, c: 3 }));
// 3
tibalt
  • 15,201
  • 1
  • 29
  • 22
10

In jQuery i've made it in a such way:

len = function(obj) {
    var L=0;
    $.each(obj, function(i, elem) {
        L++;
    });
    return L;
}
Larry Foobar
  • 11,092
  • 15
  • 56
  • 89
7

So one does not have to find and replace the Object.keys method, another approach would be this code early in the execution of the script:

if(!Object.keys)
{
  Object.keys = function(obj)
  {
    return $.map(obj, function(v, k)
    {
      return k;
    });
  };
 }
Robert Brisita
  • 5,461
  • 3
  • 36
  • 35
6

Also can be done in this way:

Object.entries(obj).length

For example:

let obj = { a: 1, b: 2, };
console.log(Object.entries(obj).length); //=> 2
// Object.entries(obj) => [ [ 'a', 1 ], [ 'b', 2 ] ]
5

Here's a jQuery-ised function of Innuendo's answer, ready for use.

$.extend({
    keyCount : function(o) {
        if(typeof o == "object") {
            var i, count = 0;
            for(i in o) {
                if(o.hasOwnProperty(i)) {
                    count++;
                }
            }
            return count;
        } else {
            return false;
        }
    }
});

Can be called like this:

var cnt = $.keyCount({"foo" : "bar"}); //cnt = 1;
Andrew Plank
  • 942
  • 10
  • 22
4

One more answer:

var j = '[{"uid":"1","name":"Bingo Boy", "profile_img":"funtimes.jpg"},{"uid":"2","name":"Johnny Apples", "profile_img":"badtime.jpg"}]';

obj = Object.keys(j).length;
console.log(obj)
Mahendra Kulkarni
  • 1,437
  • 2
  • 26
  • 35
3

For those coming here to find the item count of something that is already a jQuery object:
.length is what you are looking for:

Example:

len = $('#divID').length;
alert(len);
Jpsy
  • 20,077
  • 7
  • 118
  • 115
1

If you want to avoid new dependencies you could make your own smart objects. Of course only if you want to do more that just get it's size.

MyNeatObj = function (obj) {
  var length = null;

  this.size = function () {
    if (length === null) {
      length = 0;
      for (var key in obj) length++;
    }
    return length;
  }
}

var thingy = new MyNeatObj(originalObj);
thingy.size();
doublejosh
  • 5,548
  • 4
  • 39
  • 45
0

You might have an undefined property in the object. If using the method of Object.keys(data).length is used those properties will also be counted.

You might want to filter them out out.

Object.keys(data).filter((v) => {return data[v] !== undefined}).length
Yaki Klein
  • 3,978
  • 3
  • 37
  • 34
-1

You may use something like Lodash lib and _.toLength(object) should give you the length of your object

Hamatek
  • 39
  • 8
-1

You could add another name:value pair of length, and increment/decrement it appropriately. This way, when you need to query the length, you don't have to iterate through the entire objects properties every time, and you don't have to rely on a specific browser or library. It all depends on your goal, of course.

ajq88
  • 305
  • 1
  • 14