The Object getOwnPropertyNames() method

By

Learn how the JavaScript Object.getOwnPropertyNames() method returns all own property names, including non-enumerable ones that Object.keys() leaves out.

~~~

Object.getOwnPropertyNames() returns an array containing all the names of the own properties of the object passed as argument, including non-enumerable properties. It does not consider inherited properties.

Example:

const dog = {}
dog.breed = 'Siberian Husky'
dog.name = 'Roger'

Object.getOwnPropertyNames(dog) //[ 'breed', 'name' ]

What’s the difference with Object.keys()?

For a plain object like the one above, none. Both return ['breed', 'name'].

The difference shows up with non-enumerable properties. Non-enumerable properties are hidden from most iteration: they don’t appear in for..in loops, in Object.keys(), or in the result of JSON.stringify().

You create one with Object.defineProperty():

const dog = { breed: 'Siberian Husky', name: 'Roger' }

Object.defineProperty(dog, 'id', {
  value: 12,
  enumerable: false
})

Object.keys(dog) //[ 'breed', 'name' ]
Object.getOwnPropertyNames(dog) //[ 'breed', 'name', 'id' ]

Object.keys() skips id. Object.getOwnPropertyNames() lists it.

You’ll meet non-enumerable properties mostly on built-in objects, or in libraries that use defineProperty() to attach internal data they don’t want showing up in loops and serialization.

So my rule of thumb is: use Object.keys() for everyday work, and reach for Object.getOwnPropertyNames() when you’re inspecting an object and want to see everything it hides, non-enumerable properties included.

It only looks at own properties

Inherited properties never show up, no matter how the object got them:

const animal = { legs: 4 }
const cat = Object.create(animal)
cat.name = 'Luna'

Object.getOwnPropertyNames(cat) //[ 'name' ]

legs lives on the prototype, so it’s not an own property of cat, and it’s left out.

Watch out with arrays

Arrays are objects, and their length property is a non-enumerable own property. That means it appears in the result:

Object.getOwnPropertyNames(['a', 'b']) //[ '0', '1', 'length' ]

If you loop over that result expecting only the indexes, length sneaks in and breaks your logic. The fix is easy: don’t use this method on arrays. Use a regular loop, or Object.keys(), which returns just ['0', '1'].

One last thing: properties keyed by a Symbol are not included, since the method only returns string names. If you need those too, Object.getOwnPropertySymbols() returns them, and Reflect.ownKeys() returns both strings and symbols in one call.

~~~

Related posts about js: