Why does Object.keys return an Array instead of a Set?

# #!/JoePea (4 years ago)

Sets are faster, even for tiny lists of four items. See the perf tests (tested in Chrome):

twitter.com/trusktr/status/1315848017535098880

twitter.com/trusktr/status/1317281652540731392

#!/JoePea

# Jordan Harband (4 years ago)

Because Object.keys was standardized in 2009, 6 years before Set existed.

# #!/JoePea (4 years ago)

Well that makes sense! Would it be worth adding an option like Object.keys(obj, true) to return a set? Or perhaps Object.keySet(obj)? #!/JoePea

# Bruno Macabeus (4 years ago)

I think that we can't add a new parameter on Object.keys, because it could be a break change (and it will be a little bad to read). We could add a new method on Object, like Object.keysSet, but I don't know how important it is.

# Ehab Alsharif (4 years ago)

Other than the fact that Object.keys existed really before Sets, you are comparing apples and oranges here in your benchmarks. the include method has to scan the array in order to find elements, but sets are objects which are just hash tables. Also you typically don't get the keys array to check that a key is there, you can do that directly using the object you have. Another thing is that the typical use case for Object.keys is to get an iterator over the keys, returning a set for that purpose does not serve that purpose directly.

# Jordan Harband (4 years ago)

new Set(Object.keys(obj)) seems pretty straightforward - I doubt it's worth adding something to the language just to make that shorter.

Separately, if you're looking for a deduped O(1) lookup of key presence, you already have an object - Object.prototype.hasOwnProperty.call(obj, key).

# #!/JoePea (4 years ago)

Interesting, on my system I consistently see Set iteration is faster (I replayed it many times). I'm in Chrome 85, Linux. This might be temporary.

new Set(Object.keys(obj))

That creates two objects and an iteration (will the engine optimize that away?), while Object.keySet (or similar) would surely create a single object.

#!/JoePea

# Herby Vojčík (4 years ago)

On 27. 10. 2020 0:11, #!/JoePea wrote:

Interesting, on my system I consistently see Set iteration is faster (I replayed it many times). I'm in Chrome 85, Linux. This might be temporary.

new Set(Object.keys(obj))

That creates two objects and an iteration (will the engine optimize that away?), while Object.keySet (or similar) would surely create a single object.

#!/JoePea

Just a speculation here, but it depends on the shape of obj. If obj has internal map, then Object.keys(obj) is internal constant structure, known to contain unique items. If arrays have a flag for "known to be unique", maybe combined with "known to not be mutated", both new Set(...) created from such structure and iterations can be pretty well-optimized.