What's the difference between Object.getOwnPropertyNames
and Object.keys
in javascript? Also some examples would be appreciated.

- 9,690
- 6
- 37
- 56
-
4Judging from MDN articles on both, the difference is, whether the returned list includes the non-enumerable properties: [`Object.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) does not return them, while [`Object.getOwnPropertyNames()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames) does. – Sirko Mar 26 '14 at 10:46
-
6[MDN: Enumerability and ownership of properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) – Bergi Feb 25 '15 at 00:35
5 Answers
There is a little difference. Object.getOwnPropertyNames(a)
returns all own properties of the object a
. Object.keys(a)
returns all enumerable own properties. It means that if you define your object properties without making some of them enumerable: false
these two methods will give you the same result.
It's easy to test:
var a = {};
Object.defineProperties(a, {
one: {enumerable: true, value: 1},
two: {enumerable: false, value: 2},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]
If you define a property without providing property attributes descriptor (meaning you don't use Object.defineProperties
), for example:
a.test = 21;
then such a property becomes enumerable automatically and will appear in both methods’ returned arrays.

- 26,597
- 4
- 30
- 62

- 191,768
- 25
- 236
- 258
-
48In particular, the `length` properties of array objects is not enumerable, so it doesn't show up in `Object.keys`. – Barmar Apr 01 '16 at 02:04
-
10@Barmar The `length` property of objects is on the prototype, not the object itself, so neither `Object.keys` nor `Object.getOwnPropertyNames` will list it. – The Qodesmith Jun 14 '17 at 22:04
-
14@TheQodesmith the result of `Object.getOwnPropertyNames(anyArray)` includes `length` – thorn0 Oct 25 '17 at 11:11
-
9I stand corrected! `Object.getOwnPropertyNames(anyArray)` indeed does include `length` in the returned array! – The Qodesmith Oct 25 '17 at 16:35
-
Yeah, but Array.prototype has it, too. It's kind of weird that one can modify Array.prototype like a normal array (i.e. Array.prototype.push('whatever')). But it seems to have no effect on newly created Array instances. https://stackoverflow.com/questions/48020958/why-is-length-a-property-of-array-not-array-prototype-chain – trollkotze May 27 '18 at 07:59
-
DIY `length` property is not enumerable: `Object.getOwnPropertyDescriptor([], 'length')` – zurfyx Oct 13 '18 at 11:11
-
array is an Array Instance, It's nature to have its own 'length' property. Which does not mean that an ordinary object should always have an 'length' property. – TeaDrinker Feb 28 '23 at 23:57
Another difference is in case of array Object.getOwnPropertyNames
method will return an extra property that is length
.
var x = ["a", "b", "c", "d"];
Object.keys(x); //[ '0', '1', '2', '3' ]
Object.getOwnPropertyNames(x); //[ '0', '1', '2', '3', 'length' ]

- 771
- 8
- 21

- 6,119
- 10
- 45
- 56
Literal notation vs constructor when creating object. Here is something that got me.
const cat1 = {
eat() {},
sleep() {},
talk() {}
};
// here the methods will be part of the Cat Prototype
class Cat {
eat() {}
sleep() {}
talk() {}
}
const cat2 = new Cat()
Object.keys(cat1) // ["eat", "sleep", "talk"]
Object.keys(Object.getPrototypeOf(cat2)) // []
Object.getOwnPropertyNames(cat1) // ["eat", "sleep", "talk"]
Object.getOwnPropertyNames(Object.getPrototypeOf(cat2)) // ["eat", "sleep", "talk"]
cat1 // {eat: function, sleep: function, talk: function}
cat2 // Cat {}
// a partial of a function that is used to do some magic redeclaration of props
function foo(Obj) {
var propNames = Object.keys(Obj);
// I was missing this if
// if (propNames.length === 0) {
// propNames = Object.getOwnPropertyNames(Obj);
// }
for (var prop in propNames) {
var propName = propNames[prop];
APIObject[propName] = "reasign/redefine or sth";
}
}
So in my case the foo
function didn't work if I gave it objects of the cat2 type.
There are other ways to create objects so there could be other kinks in there as well.

- 1,106
- 1
- 12
- 27
-
`Object.getOwnPropertyNames` will return the property names for `cat1` and not `cat2`. The two ways of creating the object do not produce a difference between `Object.getOwnPropertyNames` and `Object.keys`. – Boric Sep 19 '19 at 19:09
-
1@Boric Yes you are correct. I could have meant to use Object.getPrototypeOf(cat2) with both methods instead of just cat2. I can't be for sure because I don't remember and don't have the code. I will fix it in the answer. – h3dkandi Sep 20 '19 at 06:38
As was already explained, .keys
doesn't return non-enumerable properties.
Regarding to examples, one of pitfall cases is an Error
object: some of its properties are non-enumerable.
So while console.log(Object.keys(new Error('some msg')))
yields []
,
console.log(Object.getOwnPropertyNames(new Error('some msg')))
yields ["stack", "message"]
console.log(Object.keys(new Error('some msg')));
console.log(Object.getOwnPropertyNames(new Error('some msg')));

- 4,048
- 2
- 29
- 34
Another difference is that (at least with nodejs) "getOwnPropertyNames" function does not guarantee keys order, that's why I usually use "keys" function :
Object.keys(o).forEach(function(k) {
if (!o.propertyIsEnumerable(k)) return;
// do something...
});

- 35
- 1
- 4
-
1Is that still the case in current versions of Node.js, and if so, do you know any examples of `getOwnPropertyNames` not being in order? Because ES2015 specifies [an order for `Obect.getOwnPropertyNames`](http://www.ecma-international.org/ecma-262/6.0/#sec-object.getownpropertynames), while the [order for `Obect.keys`](http://www.ecma-international.org/ecma-262/6.0/#sec-object.keys) is still up to the implementation. – szupie Jun 24 '16 at 03:37
-
8I always thought there was no order of JS object keys and you shouldn't rely on it even if an implementation keeps the order? – Ruan Mendes Nov 08 '16 at 22:08
-
1Um, I think it's the other way round; the order for getOwnPropertyNames is defined in the spec. Object.keys is up to the implementation. – tjvr Mar 12 '17 at 22:48
-
1All of the following have unspecified order: `for-in loop`, `Object.keys`, and `Object.getOwnPropertyNames`. That said, all three will enumerate in a consistent order with respect to one another. – Thomas Eding Oct 03 '17 at 06:30