Object.getOwnPropertyNames()

Object.keys with the filter removed. It is an introspection tool rather than an iteration tool — the properties it reveals are usually hidden for a reason.

Object static methodES5 (2009)Live demo
Common call
Object.getOwnPropertyNames(o)
Returns
every own string key
Replaces
Object.keys when non-enumerable properties matter
Watch out
still own-only, and still no symbols
Object.getOwnPropertyNames(objectobject — The object to inspect. Primitives are coerced; null and undefined throw TypeError.type: object · required)
→ string[]

Demo

Live evaluation
Try:
Inputs
jsonstringa JSON object or array
Output
Object.getOwnPropertyNames(JSON.parse('[10,20]'))
['0', '1', 'length']

The array cases are the demonstrable difference. Object.keys([10,20]) gives just the indices; this gives '0', '1' and 'length' — because length is a genuine own property of every array, merely a non-enumerable one. An empty array still has it, which is why the second case returns a one-element list rather than nothing. On a plain object parsed from JSON the two methods agree, since everything created by assignment or a literal is enumerable. What this demo cannot show is a property hidden with defineProperty, because JSON has no way to express one.

Parameters

NameTypeRequiredDescription
objectobjectyesThe object to inspect. Primitives are coerced; null and undefined throw TypeError.

Return value

string[] — Every own STRING key, enumerable or not. Symbol keys are excluded — those need getOwnPropertySymbols.

Common patterns

List a class instance methods
Prototype methods are non-enumerable.
Object.getOwnPropertyNames(Object.getPrototypeOf(instance));
Every own key, symbols included
Two calls, because neither covers both.
const all = [
  ...Object.getOwnPropertyNames(o),
  ...Object.getOwnPropertySymbols(o),
];
Prefer keys for iteration
Hidden properties are hidden deliberately.
for (const k of Object.keys(o)) { }

Examples

1. Array includes length
Object.getOwnPropertyNames([1, 2])
Returns
['0', '1', 'length']
2. keys does not
Object.keys([1, 2])
Returns
['0', '1']
3. Empty array
Object.getOwnPropertyNames([])
Returns
['length']
4. Hidden property shown
const o = {}; Object.defineProperty(o, "h", {value: 1}); Object.getOwnPropertyNames(o)
Returns
['h']
5. keys hides it
Object.keys(o)
Returns
[]
6. Symbols excluded
Object.getOwnPropertyNames({[Symbol("s")]: 1})
Returns
[]

Pitfalls

1. It is still own-only
The name says "own" and means it. Inherited properties — including every method a class defines — are absent, because those live on the prototype. Listing an instance shows its fields and none of its methods.
No methods
class A { m() {} }
Object.getOwnPropertyNames(new A())
[]
Ask the prototype
Object.getOwnPropertyNames(A.prototype)
['constructor', 'm']
2. Symbol keys are never included
Despite returning every string key regardless of enumerability, this method ignores symbols entirely. Anything keyed by Symbol.iterator or a library symbol is invisible, and needs the separate getOwnPropertySymbols call.
Missing
Object.getOwnPropertyNames({[Symbol("s")]: 1})
[]
The other half
Object.getOwnPropertySymbols({[Symbol("s")]: 1}).length
1
3. Using it to iterate data
On an array it returns length alongside the indices, so a loop over the result processes a property that is not an element. Non-enumerable generally means "not part of the data" — Object.keys is the right tool for iteration.
length included
Object.getOwnPropertyNames([1, 2]).map(k => k)
['0', '1', 'length']
Just the data
Object.keys([1, 2])
['0', '1']
4. It does not reveal private fields
A class #field is not a property at all — it is a separate internal slot. No reflection method lists it, which is what makes it genuinely private, unlike a merely non-enumerable property.
Invisible
class C { #s = 1; }
Object.getOwnPropertyNames(new C())
[]
Expose it deliberately
class C { #s = 1; get s() { return this.#s; } }
via a getter

When to use

Use it
  • Introspection, debugging and tooling
  • Listing the methods on a prototype
  • Copying an object including non-enumerable properties
  • Understanding why a property is missing from Object.keys
Reach for something else
  • Iterating data → Object.keys
  • You need symbol keys → getOwnPropertySymbols as well
  • You need inherited properties → walk the prototype chain
  • You want values or pairs → Object.values or Object.entries

Notes

Complexity
O(n) in the number of own string keys
Return
A new array of strings; the object is not modified
CPython impl
V8: Builtins-object-getownpropertynames
Memory
Allocates the key array
Thread-safe
Single-threaded; the object is only read

FAQ

Because length is a real own property that happens to be non-enumerable. Object.keys filters on the enumerable flag; this method does not. The same applies to most built-in properties, which are non-enumerable so they stay out of for...in loops.

Object.getOwnPropertyDescriptor([1], "length");
// {value: 1, writable: true, enumerable: false, configurable: false}

History

ES5
getOwnPropertyNames added with the property-attribute model.
ES2015
Symbols introduced, along with getOwnPropertySymbols and Reflect.ownKeys.