The Object getOwnPropertyNames() method
By Flavio Copes
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: