22

I'm wondering why the spec has defined Object.keys instead of Object.prototype.keys? it would surely be much better if the API was consistent, and I would like to understand why that is not the case.

Other methods are on Object.prototype, so why is this not the case?

Gras Double
  • 15,901
  • 8
  • 56
  • 54
  • Please see my update. I am not trying to be subjective, just looking to understand why the API is not designed to be consistent. –  Nov 12 '13 at 23:05
  • It's not necessarily an issue with the question, but is likely an issue with the probable answers. Nearly all are going to be speculative as few if any are going to be from members of the ECMA committee that made the decision. But, in short, they seemed to feel `Object.prototype` shouldn't be augmented further. – Jonathan Lonowski Nov 12 '13 at 23:07
  • 2
    "Primarily opinion based" is simply a best-fit response; only the people who wrote the spec have sufficient knowledge to speak on the topic. Everything else is guessing (opinion.) – Evan Davis Nov 12 '13 at 23:07
  • 1
    Okay, I'll ask on the ES6 mailing list… after I've found it! –  Nov 12 '13 at 23:08
  • So why not reword it to "What problems might putting the keys method in my object prototype cause?"...not opinion based but still kind oft the same question with responses helping if someone thinks about doing such things. – homtg Nov 12 '13 at 23:19
  • Mailing lists and wiki: http://www.ecmascript.org/community.php – apsillers Nov 12 '13 at 23:54
  • They could have used a – Nick Manning Mar 07 '15 at 12:32
  • See also [Why is it Object.defineProperty() rather than this.defineProperty() (for objects)?](https://stackoverflow.com/q/13239317/1048572) – Bergi Jul 14 '19 at 09:18
  • See also [Why were ES5 Object methods not added to Object.prototype?](http://stackoverflow.com/q/9735026/1048572) – Bergi Oct 01 '22 at 14:48

2 Answers2

4

Because you could easily override that by defining your object with a key called keys holding a value or a function.

var myObj = {
  val1: 'hi',
  keys: function() {
    return true;
  }
};

What would you expect to be returned by myObj.keys()?

homtg
  • 1,999
  • 1
  • 15
  • 20
  • 7
    But this is true of any method in the prototype. Why single this one out? – Evan Davis Nov 12 '13 at 22:54
  • 2
    @Mathletics It wasn't. Most of the new Object methods added in ES5 are methods of the `Object` constructor rather than its `prototype`. – Jonathan Lonowski Nov 12 '13 at 22:57
  • 2
    This doesn't make sense. Where's the consistency? :-S –  Nov 12 '13 at 22:59
  • @JonathanLonowski sure, but that doesn't change my question. Why is _any_ of those methods not part of the prototype? – Evan Davis Nov 12 '13 at 23:06
  • 6
    @Mathletics maybe because the method "keys" is much more likely to be accidently overriden as, lets say, the method "hasOwnProperty", simply because of the more generic name? – basilikum Nov 12 '13 at 23:06
4

I would assume they did this because it's not always clear what are keys and what are not, for instance:

var cls = function() {
    this.IAMAKEY = undefined;
    this.someMethod = function() {};
};

Object.keys(new cls()); // ['IAMAKEY', 'someMethod']

Incidentally, adding Object.prototype.keys, returns the keys method :)

But if you must:

Object.defineProperty(Object.prototype, 'keys', {
    writable: false,
    configurable:   false,
    value:          function() {
        return Object.keys(this);
    }
});
peterjwest
  • 4,294
  • 2
  • 33
  • 46
ansiart
  • 2,563
  • 2
  • 23
  • 41