Object.getOwnPropertyNames vs Object.keys

Javascript

Javascript Problem Overview


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

Javascript Solutions


Solution 1 - Javascript

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.

Solution 2 - Javascript

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

Solution 3 - Javascript

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.

Solution 4 - Javascript

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

Solution 5 - Javascript

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkamilkpView Question on Stackoverflow
Solution 1 - JavascriptdfsqView Answer on Stackoverflow
Solution 2 - JavascriptmanasView Answer on Stackoverflow
Solution 3 - Javascripth3dkandiView Answer on Stackoverflow
Solution 4 - JavascriptShimon SView Answer on Stackoverflow
Solution 5 - JavascriptOlivier PenhoatView Answer on Stackoverflow