I frequently get an array of an objects keys using:
Object.keys(someobject)
I'm comfortable doing this. I understand that Object is the Object constructor function, and keys() is a method of it, and that keys() will return a list of keys on whatever object is given as the first parameter. My question is not how to get the keys of an object - please do not reply with non-answers explaining this.
My question is, why isn't there a more predictable keys() or getKeys() method, or keys instance variable available on Object.prototype, so I can have:
someobject.keys()
or as an instance variable:
someobject.keys
And return the array of keys?
Again, my intention is to understand the design of Javascript, and what purpose the somewhat unintuitive mechanism of fetching keys serves. I don't need help getting keys.
Feel free to make your own, but the more properties you add to the
Object
prototype, the higher chance you'll collide. These collisions will most likely break any third party javascript library, and any code that relies on afor...in
loop.I suppose they don't want too many properties on
Object.prototype
since your own properties could shadow them.The more they include, the greater the chance for conflict.
It would be very clumsy to get the keys for this object if
keys
was on theprototype
...An example of how introducing potentially shadowed properties can break code.
There seems to be some confusion as to why it's a big deal to add new properties to
Object.prototype
.It's not at all difficult to conceive of a bit of code in existence that looks like this...
Clearly this code would break if you add a
keys
function toObject.prototype
. The fact thatsomeObject.keys
would now be a shadowing property breaks the code that is written to assume that it is not a shadowing property.Hindsight is 20/20
If you're wondering why
keys
wasn't part of the original language, so that people would at least be accustomed to coding around it... well I guess they didn't find it necessary, or simply didn't think of it.There are many possible methods and syntax features that aren't included in the language. That's why we have revisions to the specification, in order to add new features. For example,
Array.prototype.forEach
is a late addition. But they could add it toArray.prototype
, because it doesn't break proper uses ofArray
.It's not a realistic expectation that a language should include every possible feature in its
1.0
release.Since
Object.keys
does nothing more than return an Array of an Object's enumerable own properties, it's a non-essential addition, that could be achieved with existing language features. It should be no surprise that it wasn't present earlier.Conclusion
Adding
keys
toObject.prototype
most certainly would break legacy code.In a tremendously popular language like JavaScript, backward compatibility is most certainly going to be an important consideration. Adding new properties to
Object.prototype
at this point could prove to be disastrous.I guess an answer to your question is "Because the committee decided so", but I can already hear you ask "why?" before the end of this sentence.
I read about this recently but I can't find the source right now. What it boiled down to was that in many cases you had to use
Object.prototype.keys.call(myobject)
anyway, because the likelihood ofmyobject.keys
already being used in the object for something else.I think you will find this archived mail thread interesting, where for example Brendan Eich discuss some aspects of the new methods in ECMAScript 5.
Update: While digging in the mail-archive I found this: