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

2

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 property becomes an enumerable automatically and both methods produce the same array.

6

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' ] 

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.

2

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')));
0

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... }); 
4

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy