171

Suppose I have the following object in JavaScript:

var object = {
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}; 

How do I find out how many values exist in the object?

Sasha Chedygov
  • 116,670
  • 26
  • 98
  • 110
Eugeniu Torica
  • 6,986
  • 11
  • 44
  • 61
  • 7
    Hold on! JS has no tuples and no dictionaries. That is called an object (written in literal notation), although it looks like a Python dictionary. What do you call a tuple in the above example though? – Ionuț G. Stan Aug 28 '09 at 09:36
  • How do you suggest to rename this question? – Eugeniu Torica Aug 28 '09 at 09:44
  • Maybe "attributes" instead of "tuples"? That's assuming you want the answer to be 3 with the above 'object'. – Warren Young Aug 28 '09 at 09:50
  • duplicate of http://stackoverflow.com/questions/956719/number-of-elements-in-a-javascript-object ; http://stackoverflow.com/questions/126100/how-to-efficiently-count-the-number-of-keys-properties-of-an-object-in-javascript and possibly other questions – Christoph Aug 28 '09 at 14:06
  • 1
    Yeah. It is duplicated because I didn't know how to ask properly. We can close it as a duplicate. – Eugeniu Torica Aug 28 '09 at 14:24
  • 26
    It's simple, guys: `Object.keys(myObject).length`, see my post. – deadrunk Nov 02 '12 at 07:20
  • There is another answer which seems more suitable, would you reconsider you accepted answer? – Qwerty Jan 11 '14 at 01:48
  • @deadrunk you should post it as an answer it is far more better than the one accepted... – eduyayo Apr 18 '16 at 14:44

9 Answers9

541

You can do that by using this simple code:

Object.keys(myObject).length
deadrunk
  • 12,675
  • 4
  • 27
  • 29
  • 2
    This is far from fully supported: http://kangax.github.io/es5-compat-table/ – Andrew Sep 27 '13 at 00:55
  • 19
    @Andrew I wouldn't say "far from fully" I would say not supported in IE8 and below. Also, [Polyfill](http://jsperf.com/polyfill-object-keys). – hitautodestruct Nov 28 '13 at 09:25
  • Fair enough, it is not supported in IE8 or below. If that is a problem, test for the existence of keys() on Object (or try-catch), and fall back. – Andrew Nov 29 '13 at 04:02
  • 23
    If community can close questions, community should be able to change correct answer. – Case Apr 12 '14 at 21:29
  • 12
    This should definitively be the correct answer, it's simple and elegant! @Iscariot +1: can't agree more! – tanou Oct 03 '14 at 09:41
  • In case someone needs support for IE8 and below a simple fallback: http://tokenposts.blogspot.com.au/2012/04/javascript-objectkeys-browser.html – Savas Vedova Apr 06 '15 at 21:36
  • 10
    This should be the accepted answer, I don't think the argument that "but it doesn't work in IE8" is any excuse. The only possible reason for trying to support it is if industry are still using windows XP. In which case, I think switching to an alternative browser is a better choice, continuing to develop and support IE8 is a long road thats going nowhere, you are going to have to re-work your code at some point if it only works in IE. – Morvael Apr 17 '15 at 11:29
  • @Andrew no one uses ie8 anymore. Please retract your comment. – Darth Egregious Aug 21 '15 at 14:17
  • 1
    @Fuser97381: The whole of South Korea uses older version of IE. – Andrew Sep 08 '15 at 00:40
  • 6
    If you want to write your code to cater to tech backwaters, feel free. I hope you also optimize all your code for 2400 baud connections. Enjoy living in the past. – Darth Egregious Sep 08 '15 at 02:44
  • Life saver. This should be the accepted answer. – Nishant Ghodke Jun 23 '16 at 10:43
  • @NishantGhodke I was about to write your comment haha – Teoman Tıngır Sep 16 '18 at 19:46
  • 1
    Hahahaha @DarthEgregious. The "2400 baud" comment was priceless. – Art Geigel Jul 21 '20 at 12:32
112

There's no easy answer, because Object — which every object in JavaScript derives from — includes many attributes automatically, and the exact set of attributes you get depends on the particular interpreter and what code has executed before yours. So, you somehow have to separate the ones you defined from those you got "for free."

Here's one way:

var foo = {"key1": "value1", "key2": "value2", "key3": "value3"};
Object.prototype.foobie = 'bletch'; // add property to foo that won't be counted

var count = 0;
for (var k in foo) {
    if (foo.hasOwnProperty(k)) {
       ++count;
    }
}
alert("Found " + count + " properties specific to foo");

The second line shows how other code can add properties to all Object derivatives. If you remove the hasOwnProperty() check inside the loop, the property count will go up to at least 4. On a page with other JavaScript besides this code, it could be higher than 4, if that other code also modifies the Object prototype.

Warren Young
  • 36,691
  • 8
  • 76
  • 94
  • 3
    You shouldn't use an empty object to access Object.prototype. Just use Object.prototype.hasOwnProperty.call(foo, k). – Eli Grey Aug 28 '09 at 17:01
  • 1
    why don't you just do foo.hasOwnProperty(k). Am I missing something? I mean even JavaScript type derives from Object.prototype, and it will have a hasOwnProperty() method. – bucabay Aug 28 '09 at 17:10
  • @Elijah: I don't see what's wrong with the way I did it, but yes, your way should work, too. – Warren Young Aug 28 '09 at 22:00
  • 2
    @bucabay: The purpose of the test is to find those properties of 'foo' that aren't present on every other Object derivative. It might be enlightening to remove the test, and see how high count goes. You'll find it to be in the dozens. Just for one, you'll find a reference to "hasOwnProperty()" in both 'foo' and 'empty', because "member functions" are properties of objects, too, not just data as in some other languages. – Warren Young Aug 28 '09 at 22:04
  • @WarrenYoung The statement empty.hasOwnProperty(k) will always be FALSE since empty objects have no immediate properties. foo.hasOwnProperty(k) will return only immediate properties, not inherited properties from Object.prototype. – bucabay Aug 31 '09 at 21:24
  • Try doing a test with: `Object.prototype.example = true;` – bucabay Aug 31 '09 at 21:25
  • I see the problem now. It's fixed, and I've added more to my answer to illustrate the point. – Warren Young Sep 01 '09 at 10:01
51

Use underscore library, very useful: _.keys(obj).length.

HardlyNoticeable
  • 424
  • 5
  • 20
Alex M
  • 1,304
  • 1
  • 13
  • 23
12

You can iterate over the object to get the keys or values:

function numKeys(obj)
{
    var count = 0;
    for(var prop in obj)
    {
        count++;
    }
    return count;
}

It looks like a "spelling mistake" but just want to point out that your example is invalid syntax, should be

var object = {"key1":"value1","key2":"value2","key3":"value3"};
nexus
  • 505
  • 2
  • 13
11
 var miobj = [
  {"padreid":"0", "sw":"0", "dtip":"UNO", "datos":[]},
  {"padreid":"1", "sw":"0", "dtip":"DOS", "datos":[]}
 ];
 alert(miobj.length) //=== 2

but

 alert(miobj[0].length) //=== undefined

this function is very good

Object.prototype.count = function () {
    var count = 0;
    for(var prop in this) {
        if(this.hasOwnProperty(prop))
            count = count + 1;
    }
    return count;
}

alert(miobj.count()) // === 2
alert(miobj[0].count()) // === 4
pimus
  • 119
  • 1
  • 2
5

This function makes use of Mozilla's __count__ property if it is available as it is faster than iterating over every property.

function countProperties(obj) {
  var count = "__count__",
  hasOwnProp = Object.prototype.hasOwnProperty;

  if (typeof obj[count] === "number" && !hasOwnProp.call(obj, count)) {
    return obj[count];
  }
  count = 0;
  for (var prop in obj) {
    if (hasOwnProp.call(obj, prop)) {
      count++;
    }
  }
  return count;
};

countProperties({
  "1": 2,
  "3": 4,
  "5": 6
}) === 3;
Eli Grey
  • 32,712
  • 13
  • 69
  • 92
  • Note that this attribute was deprecated in Firefox 4 and removed shortly thereafter, so it hasn't been present in any browser for several years. – Sasha Chedygov Jun 26 '17 at 22:09
4

EDIT: this will case errors with jquery to happen, plus some other inconveniences. YOU SHOULD NOT USE IT: (perhaps if one could add a privaate method instead of a public property function, this would be OK, but don't have the time now). Community wikied

do not use:

Even though javascript's object by default doesn't have the count function, classes are easily extendable, and one can add it oneself:

Object.prototype.count = function () {
    var count = 0;
    for(var prop in this) {
        if(this.hasOwnProperty(prop))
            count = count + 1;
    }
    return count;
}

So that after that one can execute

var object = {'key1': 'val1', 'key2':'val2', 'key3':'val3'};
console.log(object.count()); // 3

As a conclusion, if you want count functionality in objects, you need to copy the code from code block 1, and paste it early in execution time ( before you call the count ).

Let me know if that works for you!

Regards, Pedro

Pedro
  • 941
  • 10
  • 16
  • Hi. i have been using this for a while with no problems... the only issue I found is that if you loop on objects after impementing this property on all objects, it'll perform an extra loop. If anyone can find a workarround, that'd be great – Pedro Feb 21 '11 at 12:07
  • huh? why not? someone might ifx it – Pedro Jul 15 '11 at 15:00
  • IMO extending standard types isn't best idea – deadrunk Dec 02 '13 at 02:26
  • I agree, but our rubyist community might not. ;) – Pedro Dec 02 '13 at 02:38
1

For those which will read this question/answers, here is a JavaScript implementation of Dictionary collection very similar as functionality as .NET one: JavaScript Dictionary

Michael H.
  • 237
  • 1
  • 4
  • 11
-4

Although it wouldn't be a "true object", you could always do something like this:

var foo = [
  {Key1: "key1"},
  {Key2: "key2"},
  {Key3: "key3"}
];

alert(foo.length); // === 3
Shaz
  • 14,594
  • 3
  • 39
  • 57