1702

What's the fastest way to count the number of keys/properties of an object? It it possible to do this without iterating over the object? i.e. without doing

var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;

(Firefox did provide a magic __count__ property, but this was removed somewhere around version 4.)

Luc125
  • 5,365
  • 29
  • 34
mjs
  • 57,072
  • 26
  • 82
  • 114

20 Answers20

2759

To do this in any ES5-compatible environment, such as Node, Chrome, IE 9+, Firefox 4+, or Safari 5+:

Object.keys(obj).length
Zsolt Meszaros
  • 8,506
  • 12
  • 20
  • 30
Avi Flax
  • 46,847
  • 9
  • 42
  • 61
  • 8
    Not just Node.js, but any environment that supports ES5 – Yi Jiang Apr 03 '11 at 23:38
  • 60
    BTW... just ran some tests... this method runs in O(n) time. A for loop isn't much worse than this method. ** sad face ** http://stackoverflow.com/questions/7956554/efficiently-counting-the-number-of-keys-properties-of-an-object-in-javascript – BMiner Oct 31 '11 at 16:58
  • 3
    @BMiner that's a shame, but this approach still has the advantages of concision and clarity. – Avi Flax Nov 06 '11 at 00:22
  • 1
    It must be O(n) since it's creating a new list of size n. i.e. `var o = {a: 1, b: 2}; Object.keys(o).slice(1)` doesn't affect o. I still don't think there is a better answer than this though! – Mark Rhodes Jan 11 '12 at 13:53
  • 174
    -1 (-200 if I could) This not only iterates through the object but also creates a whole new array with all its keys, so it completely fails at answering the question. – GetFree Jun 22 '12 at 14:28
  • 43
    It seems much faster than doing the for (at least on Chrome 25): http://jsperf.com/count-elements-in-object – fserb Nov 18 '12 at 15:51
  • @fserb Interesting! Maybe some optimisation? And the FF "loop 2" result is an interesting outlier--5x faster than anything else. – mjs Dec 03 '12 at 11:22
  • @fserb yeah but only if you repeatedly call it... basically you test the run time of a function call. added a cached test, only calling Object.keys once. same speed. – bernstein Mar 06 '13 at 22:45
  • @mjs likely a erroneous optimization, no longer faster on ffx 21. – bernstein Mar 06 '13 at 22:53
  • @ceram1 Are you sure about that? Does the return value of `map.keys()` reflect changes made to `map` after the `.keys()` call? – Keen Apr 02 '14 at 17:24
  • @ceram1 Java != javascript ; You seem to be confusing the two. – Tim Tisdall May 05 '14 at 14:16
  • 1
    @ceram1 In this case, people only care how javascript _is_ implementing the `Object.keys()` method, regardless of what is "normal". Pointing out how Java does something has no bearing on this conversation. – Tim Tisdall May 05 '14 at 15:33
  • @TimTisdall Hmm.. I think it can confuse newbies, so I'll delete comments about java. Object.keys . According to spec http://es5.github.io/#x15.2.3.14 . It doesn't specified if it's clone or original. In chrome, it said "since the result is mutable we have to create a fresh clone on each invocation." Sorry for confusing, but it's okay to use Object.keys as fixed array is very fast. – ceram1 May 06 '14 at 03:34
  • 1
    This question is a few years old now, but for anyone who is looking at the speed test results above, I ran the exact same test using lodash instead of underscore: http://jsperf.com/count-elements-in-object/12 lodash kicks underscore's ass – Jake Sellers Jun 04 '14 at 19:43
  • @JakeSellers: I must be mising something obvious,but what is the difference between 'underscore' and 'lodash' ? besides, on my platform both variants perform roughly identical ( both slightly above 18 kOps/s ). – collapsar Jun 06 '14 at 09:08
  • @collapsar, I won't go way into it, but one of the devs that was working on underscore didn't like how inconsistently the underscore functions were being developed(how they work, what they retuarn, etc) and decided to create his own lib called lodash(ba-dum-tish). Its generally faster, has more features, and is just plain better(IMO). If you're so inclined you can find discussions(arguments) between the two lead devs on several different boards that give insite into why the split happened. – Jake Sellers Jun 08 '14 at 19:10
  • 1
    Even though this creates a whole new array, it's still quick. This is probably because it is implemented in native C or C++, so even though it may not be as efficient, since C and C++ are so much faster intrinsically it still may be faster – user3413723 Jun 21 '15 at 18:27
  • Solved a similar issue in couchdb too: "listByUniversityId": { "map": "function(doc) {\n if(doc.type === 'ghgReport')\n \temit(doc.universityId,Object.keys(doc.reports).length);\n}" } – Dave K Oct 23 '15 at 16:41
  • I am having a hard explaining my question, but lets say I have a function prototype that sort of extends my object and I only want to count the properties that have normal values (EX: string, int) – realappie Dec 02 '15 at 20:08
  • Not useful for traversing parsed JSON objects. – Throw Away Account Apr 05 '16 at 15:46
  • 39
    @GetFree Why so many thumbs up? This is definitely the fastest way in terms of coding. No extra methods or libraries required. In terms of code speed, apparently it's not too bad either. Not a complete fail at all. 87 thumbs up fails for you. – Andrew Jun 02 '16 at 17:31
  • 3
    This iterates over the object. The question specifically is asking for solutions that do not iterate over the object. – Michael Matthew Toomim Nov 15 '16 at 08:31
  • 1
    @GetFree Depending on how a JS environment implements objects, counting the number of properties that an object has might unavoidably be an O(n) operation with respect to the number of properties. If so, this would mean that iterating over all of the properties, explicitly or not, *is* the most efficient approach. (I don't know how JS environments implement objects, so this is speculation on my part.) – Kevin Dec 16 '16 at 22:03
  • 1
    If you have a list of potential keys, it is 10x faster to try all keys. I was quite surprised, but the tests prove it: https://jsperf.com/count-elements-in-object/22 – Vassil Lunchev Jul 01 '19 at 15:49
  • 1
    It doesn't have to iterate over the object(it just does on some vm's). But its thumb upped because it works and is solution for most people who come across this question from google looking for a quick way to get a count of the keys. The people thumbing it up don't really care what happens under the hood. – Lassi Kinnunen Dec 17 '19 at 07:52
  • 1
    @GetFree then what's the the optimal approach? – user1886304 Apr 04 '20 at 17:10
  • Of course we care if what is under the hood has issues! The optimal approach is to use babel to compile efficiency or rely on V8, Servo, or whatever supported browser engine to perform optimizations. If you find inefficiency, file a bug there. Lets also put an end to micro-profiling (it is fine for it to run a slower at first while it performs run-time optimizations). – TamusJRoyce Apr 11 '20 at 15:29
  • 1
    When *you* are in control of the object, (your own code is the only thing adding properties to it), then you could increment a separate counter variable whenever you add a new property, or decrement when you remove a property. This should be faster than any solution related to keys(). It's not an "atomic" thread-safe operation, but for many situations it's fine. And certainly fast. – Chris Janicki Jun 24 '20 at 21:27
  • @GetFree One O(1) alternative that I can think of is to make a wrapper class of Object and cont every time something gets added or removed. Also you could write a transpiler that constructs this class from a syntax sugar. Let me know if there are better ideas. P.S. There are a lot of O(1) improvement that can be made to the current version of JS, including this one and selecting randomly from an object etc. I sincerely hope that these features will be available in the next version of ES and that the abusing of Object.keys() will stop being necessary. – Y. Yoshii Dec 03 '20 at 13:17
157

You could use this code:

if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [],
            k;
        for (k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}

Then you can use this in older browsers as well:

var len = Object.keys(obj).length;
Renaat De Muynck
  • 2,918
  • 1
  • 18
  • 18
  • 3
    What is the purpose of the check `(Object.prototype.hasOwnProperty.call(obj, k))`? – styfle May 14 '12 at 21:04
  • 15
    @styfle If you use a _for_ loop to iterate over the object's properties, you also get the properties in the prototype chain. That's why checking `hasOwnProperty` is necessary. It only returns properties set on the object itself. – Renaat De Muynck May 21 '12 at 09:44
  • I guess I'm confused because you use `call` on `hasOwnProperty` instead of just using `Object.prototype.hasOwnProperty(obj, k)`. What's the purpose of this? – styfle May 21 '12 at 16:24
  • 15
    @styfle To make it simpler you could just write `obj.hasOwnProperty(k)` (I actually did this in my original post, but updated it later). `hasOwnProperty` is available on every object because it is part of the `Object`'s prototype, but in the rare event that this method would be removed or overridden you might get unexpected results. By calling it from `Object.prototype` it makes it little more robust. The reason for using `call` is because you want to invoke the method on `obj` instead of on the prototype. – Renaat De Muynck May 23 '12 at 20:59
  • 6
    Would not it better to use this version ? https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys – Xavier Delamotte Jan 23 '13 at 14:28
  • 1
    @XavierDelamotte You are absolutely correct. While my version works, it is very basic and ment as an example. Mozilla's code is more safe. (PS: Your link is also in the accepted answer) – Renaat De Muynck Jan 30 '13 at 17:39
  • for the new-comer to js looking at this answer... DO NOT ever modify default javascript classes, ever! – Dmitry Matveev Nov 16 '16 at 22:43
  • @Dmitry This code does not modify a default class. It only adds a shim to mimic standard functionality if it does not exists. – Renaat De Muynck Nov 17 '16 at 15:36
  • @RenaatDeMuynck and now tell me what happens when method named 'keys' becomes a standard in ecmaScript? And while you are at it think about what specification it might have... – Dmitry Matveev Nov 17 '16 at 19:11
  • @DmitryMatveev It's already a standard (http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.14). This code adds standard behavior where it's missing. – Renaat De Muynck Nov 18 '16 at 14:53
  • @RenaatDeMuynck http://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice – Dmitry Matveev Nov 18 '16 at 20:06
  • 1
    @DmitryMatveev Perhaps I am not making my point clear: It is not a good practice to extend native object protoypes *except* when implementing missing standard features (read the following carefully: https://developer.mozilla.org/nl/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Bad_practice_Extension_of_native_prototypes). So as I stated in my previous comment: `Object.keys` *is* now a standard en *should* be implemented in older browser in this manner. I would suggest to read everything carefully once more before you comment on this again... – Renaat De Muynck Nov 21 '16 at 09:58
  • This gives same result as: `Object.getOwnPropertyNames(obj).length`; much simpler. – Wilt Feb 27 '20 at 16:28
  • @Wilt Actually, there is a difference. As stated in [@BenderTheOffender's answer](https://stackoverflow.com/a/14377849/288264), `getOwnPropertyNames` also counts non-enumerable properties. It all depends on the needs of the OP. But since he didn't specify, `Object.getOwnPropertyNames(obj).length` is probably better. – Renaat De Muynck May 12 '20 at 11:29
141

If you are using Underscore.js you can use _.size (thanks @douwe):
_.size(obj)

Alternatively you can also use _.keys which might be clearer for some:
_.keys(obj).length

I highly recommend Underscore, its a tight library for doing lots of basic things. Whenever possible they match ECMA5 and defer to the native implementation.

Otherwise I support @Avi's answer. I edited it to add a link to the MDC doc which includes the keys() method you can add to non-ECMA5 browsers.

Sasha Chedygov
  • 116,670
  • 26
  • 98
  • 110
studgeek
  • 12,579
  • 6
  • 78
  • 90
  • 9
    If you use underscore.js then you should use _.size instead. The good thing is that if you somehow switch from array to object or vice versa the result stays the same. – douwe Jun 20 '11 at 11:18
  • 2
    And from my understanding lodash is generally better than underscore (though they do similar things). – Merlyn Morgan-Graham Aug 02 '15 at 23:24
  • 1
    @MerlynMorgan-Graham if I recall correctly, lodash is originally a fork of underscore... – molson504x Aug 19 '15 at 12:18
  • 6
    `_.keys(obj).length` worked best for me, because my return object is sometimes a plain string with no properties within it. `_.size(obj)` gives me back the length of the string, while `_.keys(obj).length` returns 0. – Jacob Stamm Nov 23 '15 at 23:02
  • 1
    **O(n) complexity**. Lodash and Underscore use `Object.keys` internally. Underscore also copies every key into an array inside a `for..in` loop if `Object.keys` is not defined. – N. Kudryavtsev Mar 22 '19 at 13:32
90

The standard Object implementation (ES5.1 Object Internal Properties and Methods) does not require an Object to track its number of keys/properties, so there should be no standard way to determine the size of an Object without explicitly or implicitly iterating over its keys.

So here are the most commonly used alternatives:

1. ECMAScript's Object.keys()

Object.keys(obj).length; Works by internally iterating over the keys to compute a temporary array and returns its length.

  • Pros - Readable and clean syntax. No library or custom code required except a shim if native support is unavailable
  • Cons - Memory overhead due to the creation of the array.

2. Library-based solutions

Many library-based examples elsewhere in this topic are useful idioms in the context of their library. From a performance viewpoint, however, there is nothing to gain compared to a perfect no-library code since all those library methods actually encapsulate either a for-loop or ES5 Object.keys (native or shimmed).

3. Optimizing a for-loop

The slowest part of such a for-loop is generally the .hasOwnProperty() call, because of the function call overhead. So when I just want the number of entries of a JSON object, I just skip the .hasOwnProperty() call if I know that no code did nor will extend Object.prototype.

Otherwise, your code could be very slightly optimized by making k local (var k) and by using prefix-increment operator (++count) instead of postfix.

var count = 0;
for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count;

Another idea relies on caching the hasOwnProperty method:

var hasOwn = Object.prototype.hasOwnProperty;
var count = 0;
for (var k in myobj) if (hasOwn.call(myobj, k)) ++count;

Whether this is faster or not on a given environment is a question of benchmarking. Very limited performance gain can be expected anyway.

Toothbrush
  • 2,050
  • 23
  • 33
Luc125
  • 5,365
  • 29
  • 34
32

If you are actually running into a performance problem I would suggest wrapping the calls that add/remove properties to/from the object with a function that also increments/decrements an appropriately named (size?) property.

You only need to calculate the initial number of properties once and move on from there. If there isn't an actual performance problem, don't bother. Just wrap that bit of code in a function getNumberOfProperties(object) and be done with it.

hitautodestruct
  • 17,533
  • 13
  • 59
  • 88
Confusion
  • 14,331
  • 7
  • 43
  • 71
  • 5
    @hitautodestruct Because he offers a solution. – crush Feb 10 '13 at 21:12
  • @crush This answer seems to suggest things to do rather than give a direct solution. – hitautodestruct Feb 11 '13 at 06:40
  • 5
    @hitautodestruct it suggests an answer: incrementing/decrementing an encapsulated count with the add/remove methods. There is another answer exactly like this below. The only difference is, Confusion did not offer any code. Answers are not mandated to provide code solutions only. – crush Feb 11 '13 at 14:25
  • @crush Right you are, but they should not start with a question. Fixed :) – hitautodestruct Feb 11 '13 at 18:40
  • 1
    it may not be perfect ... but compared with the other "answers" this may be the best solution for some situations – d.raev Jul 22 '16 at 12:46
  • 1
    So far this is the only solution I see that is O(1) constant time performance complexity, and therefore is the only solution that Answers the Question detail of "without iterating" and should therefore be the tru Accepted Answer. Most if not all other answers don't answer that, because they offer an O(n) linear time performance complexity; that's the case also for the 1-line solutions that call something like a .keys() function, as such function calls are O(n). – cellepo May 30 '18 at 17:38
24

Here are some performance tests for three methods;

https://jsperf.com/get-the-number-of-keys-in-an-object

Object.keys().length

20,735 operations per second

Very simple and compatible. Runs fast but expensive because it creates a new array of keys, which that then gets thrown away.

return Object.keys(objectToRead).length;

loop through the keys

15,734 operations per second

let size=0;
for(let k in objectToRead) {
  size++
}
return size;

Slightly slower, but nowhere near the memory usage, so probably better if you're interested in optimising for mobile or other small machines

Using Map instead of Object

953,839,338 operations per second

return mapToRead.size;

Basically, Map tracks its own size so we're just returning a number field. Far, far faster than any other method. If you have control of the object, convert them to maps instead.

Steve Cooper
  • 17,836
  • 14
  • 66
  • 81
17

As stated by Avi Flax https://stackoverflow.com/a/4889658/1047014

Object.keys(obj).length

will do the trick for all enumerable properties on your object but to also include the non-enumerable properties you can instead use the Object.getOwnPropertyNames. Here's the difference:

var myObject = new Object();

Object.defineProperty(myObject, "nonEnumerableProp", {
  enumerable: false
});
Object.defineProperty(myObject, "enumerableProp", {
  enumerable: true
});

console.log(Object.getOwnPropertyNames(myObject).length); //outputs 2
console.log(Object.keys(myObject).length); //outputs 1

console.log(myObject.hasOwnProperty("nonEnumerableProp")); //outputs true
console.log(myObject.hasOwnProperty("enumerableProp")); //outputs true

console.log("nonEnumerableProp" in myObject); //outputs true
console.log("enumerableProp" in myObject); //outputs true

As stated here this has the same browser support as Object.keys

However, in most cases, you might not want to include the nonenumerables in these type of operations, but it's always good to know the difference ;)

Community
  • 1
  • 1
  • 1
    Thumbs up for mentioning `Object.getOwnPropertyNames`, you were the only one here... – Wilt Feb 27 '20 at 16:31
14

I'm not aware of any way to do this, however to keep the iterations to a minimum, you could try checking for the existance of __count__ and if it doesn't exist (ie not Firefox) then you could iterate over the object and define it for later use eg:

if (myobj.__count__ === undefined) {
  myobj.__count__ = ...
}

This way any browser supporting __count__ would use that, and iterations would only be carried out for those which don't. If the count changes and you can't do this, you could always make it a function:

if (myobj.__count__ === undefined) {
  myobj.__count__ = function() { return ... }
  myobj.__count__.toString = function() { return this(); }
}

This way anytime you reference myobj.__count__ the function will fire and recalculate.

Luke Bennett
  • 31,586
  • 3
  • 28
  • 55
  • 13
    Note that `Object.prototype.__count__` is being removed in Gecko 1.9.3: http://whereswalden.com/2010/04/06/more-changes-coming-to-spidermonkey-the-magical-__count__-property-of-objects-is-being-removed/ – dshaw Apr 20 '10 at 16:27
  • 17
    Now that Firefox 4 is out, this answer is now obsolete. `Object.__count__` is gone, and good riddance too. – Yi Jiang Apr 03 '11 at 23:50
  • 1
    I wouldn't say the answer is obsolete. It's still an interesting strategy to encapsulate a value in a function. – devios1 Jul 12 '11 at 13:30
  • should be using the prototype object to extend – Aaria Carter-Weir Sep 01 '11 at 08:25
14

as answered above: Object.keys(obj).length

But: as we have now a real Map class in ES6, I would suggest to use it instead of using the properties of an object.

const map = new Map();
map.set("key", "value");
map.size; // THE fastest way
Flavien Volken
  • 14,820
  • 9
  • 78
  • 105
13

To iterate on Avi Flax answer Object.keys(obj).length is correct for an object that doesnt have functions tied to it

example:

obj = {"lol": "what", owo: "pfft"};
Object.keys(obj).length; // should be 2

versus

arr = [];
obj = {"lol": "what", owo: "pfft"};
obj.omg = function(){
    _.each(obj, function(a){
        arr.push(a);
    });
};
Object.keys(obj).length; // should be 3 because it looks like this 
/* obj === {"lol": "what", owo: "pfft", omg: function(){_.each(obj, function(a){arr.push(a);});}} */

steps to avoid this:

  1. do not put functions in an object that you want to count the number of keys in

  2. use a seperate object or make a new object specifically for functions (if you want to count how many functions there are in the file using Object.keys(obj).length)

also yes i used the _ or underscore module from nodejs in my example

documentation can be found here http://underscorejs.org/ as well as its source on github and various other info

And finally a lodash implementation https://lodash.com/docs#size

_.size(obj)

Belldandu
  • 1,660
  • 13
  • 16
  • In response to your comments about `Array(obj).length`: It doesn't work. [http://jsfiddle.net/Jhy8M/](http://jsfiddle.net/Jhy8M/) – Jamie Chong Apr 10 '14 at 00:06
  • yeah i looked into it a bit more im going to end up removing this answer if possible or just editing it all together – Belldandu May 22 '14 at 15:28
  • I'm not seeing that this has anything to do with functions, for one, and in Chrome I don't see this behavior at all. I would suspect this may have had to do with the default behavior of [Object.defineProperty():enumerable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Description) which is `false`, though I've not yet found any documentation on how `var obj = { a: true, b: true }` may differ from `var obj = {}; obj.a = true; obj.b = true;` or simply if a different interpretation/semantics of the W3 has been adopted by Chrome. – Nolo Oct 02 '16 at 08:06
7

For those who have Underscore.js included in their project you can do:

_({a:'', b:''}).size() // => 2

or functional style:

_.size({a:'', b:''}) // => 2
hakunin
  • 3,605
  • 4
  • 35
  • 55
  • The question was not about other methods, but the fastest method. You propose using library, which already by itself fails in performance. – vanowm Mar 14 '21 at 02:31
6

From: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

Object.defineProperty(obj, prop, descriptor)

You can either add it to all your objects:

Object.defineProperty(Object.prototype, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

Or a single object:

var myObj = {};
Object.defineProperty(myObj, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

Example:

var myObj = {};
myObj.name  = "John Doe";
myObj.email = "leaked@example.com";
myObj.length; //output: 2

Added that way, it won't be displayed in for..in loops:

for(var i in myObj) {
     console.log(i + ":" + myObj[i]);
}

Output:

name:John Doe
email:leaked@example.com

Note: it does not work in < IE9 browsers.

lepe
  • 22,543
  • 9
  • 85
  • 99
  • If you’re going to extend built-in prototypes or polyfill a property (i.e. monkey-patch), please do it correctly: for forward compatibility, check if the property exists first, then make the property non-enumerable so that the own keys of constructed objects aren’t polluted. For methods use _actual_ [methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions). My recommendation: follow [these examples](https://stackoverflow.com/a/46491279/4642212) which demonstrate how to add a method that behaves as closely as possible like built-in methods. – Sebastian Simon May 09 '20 at 09:52
5

How I've solved this problem is to build my own implementation of a basic list which keeps a record of how many items are stored in the object. Its very simple. Something like this:

function BasicList()
{
   var items = {};
   this.count = 0;

   this.add = function(index, item)
   {
      items[index] = item;
      this.count++;
   }

   this.remove = function (index)
   {
      delete items[index];
      this.count--;
   }

   this.get = function(index)
   {
      if (undefined === index)
        return items;
      else
        return items[index];
   }
}
Click Upvote
  • 235,452
  • 251
  • 553
  • 736
  • 1
    Interesting alternative. This does eliminate the overhead of an aggregate counting function, but at the cost of a function call every time you add or remove an element, which unfortunately may be worse. I'd personnaly use such a list implementation for the data encapsulation and custom methods it can provide compared to a plain array, but not when I just need fast item counting. – Luc125 May 26 '13 at 19:11
  • 1
    I like your answer, but I also am a lemming and clicked upvote. This presents an interesting dilemma. You're not accounting for some behavior in your instructions, such as my situation where I've already upvoted your answer, but then I am instructed to "click upvote" and cannot. The instruction fails silently but I gather from your content here on SO that failing silently is not something you like your code doing. Just a heads up. – L0j1k Dec 01 '13 at 04:10
  • 1
    I really like this answer, nice data structure. And if there was a performance impact with the function calls on add, there would be a far greater performance boost if having to iterate over an object. This should allow for the fastest loop patten `var i = basiclist.count` `while(i--){...}` – Lex Mar 27 '14 at 22:42
  • Shouldn't a basic list at least include basic checks? Like checking if `add` replaces an old item or if `remove` is called with a non-existing index. Also it's not possible to check if the list has a given index if `undefined` is a valid item value. – Robert Jun 23 '14 at 13:39
  • Shouldn't `get` have `if (undefined === index)`? As it is the test is reversed and will use an `undefined` index to access the array. – Lawrence Dol Sep 12 '14 at 20:23
  • This is awful. If it's called a list it should behave like one. This is like some odd hybrid between a list and an object that doesn't do anything very well. I'd much rather just stick to basic data types. – Ultimate Gobblement Nov 17 '14 at 13:24
  • @UltimateGobblement where does it not behave like a list? – Click Upvote Nov 18 '14 at 18:14
  • 2
    A list should be ordered and iterable. Data is stored in an object so there's no guarantee on the ordering of elements. How do you find the length a list with holes in it? this.count? The highest index value? If you ever add two items at the same index the count goes into an error state. – Ultimate Gobblement Nov 19 '14 at 10:30
  • @UltimateGobblement Fair enough. It is called 'basicList' though, its not a end all / be all. Its meant to be extended and customized. – Click Upvote Nov 19 '14 at 15:14
  • This uses the set character of objects and if there are duplicate keys "count" wont be correct unless it takes existing keys into account. – wonko realtime Dec 11 '19 at 20:53
3

For those that have Ext JS 4 in their project you can do:

Ext.Object.getSize(myobj);

The advantage of this is that it'll work on all Ext compatible browsers (IE6-IE8 included), however, I believe the running time is no better than O(n) though, as with other suggested solutions.

Mark Rhodes
  • 9,375
  • 4
  • 44
  • 51
2

You can use:

Object.keys(objectName).length; 

and

Object.values(objectName).length;
Nino
  • 6,379
  • 2
  • 24
  • 35
Fayaz
  • 31
  • 1
1

OP didn't specify if the object is a nodeList, if it is then you can just use length method on it directly. Example:

buttons = document.querySelectorAll('[id=button)) {
console.log('Found ' + buttons.length + ' on the screen'); 
Robert Sinclair
  • 2,911
  • 25
  • 29
0

If jQuery above does not work, then try

$(Object.Item).length
Anuj Balan
  • 7,205
  • 23
  • 52
  • 89
-1

I try to make it available to all object like this:

Object.defineProperty(Object.prototype, "length", {
get() {
    if (!Object.keys) {
        Object.keys = function (obj) {
            var keys = [],k;
            for (k in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, k)) {
                    keys.push(k);
                }
            }
            return keys;
        };
    }
    return Object.keys(this).length;
},});

console.log({"Name":"Joe","Age":26}.length) //returns 2
Taquatech
  • 17
  • 3
-2

I don't think this is possible (at least not without using some internals). And I don't think you would gain much by optimizing this.

amix
  • 133
  • 1
  • 3
  • 2
    The accepted answer shows that this *can* be done, and you have no context to assert that there is nothing to gain. – Conduit Jan 20 '17 at 19:24
-2

Google Closure has a nice function for this... goog.object.getCount(obj)

look at goog.Object Documentation

Sebastian Perez
  • 438
  • 4
  • 12