It's possible to put a keys
method on Object.prototype
so that things work as you're expecting, but it's not a good idea.
Object.prototype.keys = function() {
return Object.keys(this);
};
const obj = {
prop: 'val'
};
const keys = obj.keys();
console.log(keys);
With object keys, the issue is that objects can generally have any sort of keys. The object may even have a key named keys
. So, for example:
const obj = {
name: 'building 1',
keys: 'foo'
}
Here, if you did obj.keys()
, you would get a TypeError
, because the keys
property refers to the property directly on the object, rather than the Object.prototype
method.
Object.prototype.keys = function() {
return Object.keys(this);
};
const obj = {
name: 'building 1',
keys: 'foo'
};
const keys = obj.keys();
console.log(keys);
So, the method to use to get all keys of an object was put on Object
instead, as a static method, rather than a prototype method on Object.prototype
, so as to avoid possible name collisions.
Arrays, on the other hand, are pretty much universally expected to have a certain few methods particular to arrays (like push
), and nothing else. Arrays are not generic objects - you'd pretty much always expect an array to have only array methods, and arrays almost never get arbitrary keys added to them. (If you see code that has this, it's probably code that deserves refactoring.) So, with arrays, there's no real possibility of an array method causing name collisions, like there was with a generic object.
Thus, there's no harm in having Array.prototype.push
, but Object.prototype.keys
could easily cause problems.