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