# Object.size()

**URL:** <https://es.discourse.group/t/object-size/1519>\
**Category:** 💡 Ideas\
**Created:** [November 12, 2022, 10:38pm UTC](https://es.discourse.group/t/object-size/1519 "2022-11-12T22:38:48Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![abozhilov](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/abozhilov/32/1458_2.png) [@abozhilov](https://es.discourse.group/u/abozhilov)\
**Post date:** [November 12, 2022, 10:38pm UTC](https://es.discourse.group/t/object-size/1519/1 "2022-11-12T22:38:48Z")

</div>

Hi all,

With the current version of the spec, there is no a direct way to find the number of own enumerable properties of an object.

The common pattern is:

```javascript
Object.keys(obj).length

```

Unfortunately the code above creates a temporary array with all of the own enumerable properties, which I think could be avoided if ES provides an API which returns it directly.

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [November 13, 2022, 3:02am UTC](https://es.discourse.group/t/object-size/1519/2 "2022-11-13T03:02:59Z")

</div>

Adding anything to Object.prototype is a nonstarter, and it wouldn't work on a null object anyways, so the only alternative here is something like `Object.size(obj)` - and then, what about non-enumerable keys? What about Symbol keys (enumerable and non-enumerable)? What about inherited keys?

There simply does not exist a universal definition for an object's "size", which is why `Object.keys`, or `Reflect.ownKeys`, or `Object.getOwnPropertySymbols`, or `Object.getOwnPropertyNames`, or `for (var k in obj) { }` are all available options to apply your own definition and generate the length.

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [November 13, 2022, 8:25am UTC](https://es.discourse.group/t/object-size/1519/3 "2022-11-13T08:25:26Z")

</div>

> [@abozhilov](#):
>
> Unfortunately the code above creates a temporary array with all of the own enumerable properties,

In many engines `Object.keys` tends to have an optimised fast-path, making it less expensive than it looks

Here's V8 for example: [https://github.com/v8/v8/blob/1c3b8975a4f986e4c0b07b9704ae39704c614eec/src/objects/keys.cc#L445](https://github.com/v8/v8/blob/1c3b8975a4f986e4c0b07b9704ae39704c614eec/src/objects/keys.cc#L445)

Of course this wouldn't apply to all objects, but neither would `Object.size`. If called on a proxy with a custom `ownKeys` hook, it can't skip that.

---

<div class="post-metadata">

**Author:** ![fasiha](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/fasiha/32/1700_2.png) [@fasiha](https://es.discourse.group/u/fasiha)\
**Post date:** [March 29, 2023, 2:08pm UTC](https://es.discourse.group/t/object-size/1519/4 "2023-03-29T14:08:18Z")

</div>

> [@aclaymore](#):
>
> In many engines `Object.keys` tends to have an optimised fast-path, making it less expensive than it looks

Ashley, to make sure I understand, the "fast path" in this V8 link means that `Object.keys()` would return an array that the runtime has already created and populated? Whereas the "slow path" means the whole "create a new array and populate it and then later garbage-collect it"?

Thanks for bearing with me! Just want to make sure I understand 😄

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [March 30, 2023, 8:13am UTC](https://es.discourse.group/t/object-size/1519/5 "2023-03-30T08:13:45Z")

</div>

Hi @fasiha

That's correct!

V8 source around here: [src/keys.cc - v8/v8 - Git at Google](https://chromium.googlesource.com/v8/v8/+/330e5ba26f58d0233f2904ee70ff56a8a20957ed/src/keys.cc#372)

---

<div class="post-metadata">

**Author:** ![NoM](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/nom/32/1716_2.png) [@NoM](https://es.discourse.group/u/NoM)\
**Post date:** [April 13, 2023, 3:55am UTC](https://es.discourse.group/t/object-size/1519/6 "2023-04-13T03:55:41Z")

</div>

Let's have a debate on length vs size.

It's a shame length is fairly unique to JS.

Pick one:

```javascript
Object.keys(obj).length
Object.length(obj)
Object.size(obj)

```

The odd one out is size, however length is a variable and not a function for an array. So perhaps size is the right one as that's what a Map uses.

My brain is conflicted.

And as it's most commonly used for object data tables. It should probably reflect the public members like other data structures.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [April 13, 2023, 5:23am UTC](https://es.discourse.group/t/object-size/1519/7 "2023-04-13T05:23:23Z")

</div>

Length, to me, implies an ordering as well. An array has a length because there's a start and end to the array, and the length is just the distance between those two.

Things like maps, sets, and objects are unordered. It's odd to talk about a length with them, because the data isn't conceptually lined up into a neat row with a beginning and end, it's more like a bunch of stuff in a bag. Sure, sometimes we use the Object.keys() method to force the object keys into an exact order, and after doing that we take the length, but if we're trying to count the number of properties on the object itself, .size() feels more appropriate to me.

---

<div class="post-metadata">

**Author:** ![brandonmcconnell](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/brandonmcconnell/32/2395_2.png) [@brandonmcconnell](https://es.discourse.group/u/brandonmcconnell)\
**Post date:** [March 12, 2024, 9:40pm UTC](https://es.discourse.group/t/object-size/1519/8 "2024-03-12T21:40:27Z")

</div>

I'm totally in favor of `Object.size(obj)`. Would love to stop having to write `Object.keys(obj).length` every single time I want to count its keys.

I was about to open this same issue before discovering this one. What a pain this is, and most other object types (arrays, sets, maps) have some sort of mechanism for this. Sure, those are iterables where this is not, but a `Object.size(obj)` shorthand would be very welcome.
