Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object.getOwnPropertyNames vs Object.keys

Tags:

javascript

People also ask

What is the difference between object getOwnPropertyNames and object keys?

getOwnPropertyNames(a) returns all own properties of the object a . Object. keys(a) returns all enumerable own properties.

What does object keys mean?

Description. Object. keys() returns an array whose elements are strings corresponding to the enumerable properties found directly upon object . The ordering of the properties is the same as that given by looping over the properties of the object manually.

Can an object key be an object?

The short answer is "no". All JavaScript object keys are strings. Even if you pass an object as a key, the object's toString() will be called on it, and the key will be stringified to [object Object] .

Are all keys in an object strings?

Object keys can only be strings, and even though a developer can use other data types to set an object key, JavaScript automatically converts keys to a string a value.


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.


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.


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