Object.prototype.propertyIsEnumerable()

The least-used of the three inherited introspection methods. It answers a compound question, and because false covers two very different cases it is usually clearer to ask them separately.

Object methodES3 (1999)Live demo
Common call
o.propertyIsEnumerable(k)
Returns
boolean — own AND enumerable
Replaces
a hasOwnProperty check plus a descriptor lookup
Watch out
false means "not own" OR "not enumerable" — ambiguous
object.propertyIsEnumerable(keykey — The property key to test. Non-symbols are coerced to strings.type: string | symbol · required)
→ boolean

Demo

Live evaluation
Try:
Inputs
jsonstringa JSON object or array
keystringproperty name
Output
JSON.parse('{"a":1}').propertyIsEnumerable('a')
true

The array cases show the two halves of the question. An index is an own enumerable property, so it is true — and that is why Object.keys lists it. length is a real own property of the array, but a non-enumerable one, so this returns false and Object.keys omits it. Note that the absent case and the inherited case both return false as well, which is the method weakness: a false answer cannot tell you whether the property is missing, inherited, or merely hidden.

Parameters

NameTypeRequiredDescription
keystring | symbolyesThe property key to test. Non-symbols are coerced to strings.

Return value

boolean — True only if the key is BOTH an own property and enumerable. Inherited properties and non-enumerable ones both give false, with no way to tell which.

Common patterns

Ask the two questions separately
Clearer, and each answer is unambiguous.
Object.hasOwn(o, k);
Object.getOwnPropertyDescriptor(o, k)?.enumerable;
Just use Object.keys
Enumerable own keys are exactly what it returns.
Object.keys(o).includes(k);
Borrow it safely
Same shadowing risk as hasOwnProperty.
Object.prototype.propertyIsEnumerable.call(o, k);

Examples

1. Own and enumerable
({a: 1}).propertyIsEnumerable("a")
Returns
true
2. Inherited
({}).propertyIsEnumerable("toString")
Returns
false
3. Array index
[1].propertyIsEnumerable("0")
Returns
true
4. Array length
[1].propertyIsEnumerable("length")
Returns
false
5. Defined property
const o = {}; Object.defineProperty(o, "h", {value: 1}); o.propertyIsEnumerable("h")
Returns
false
6. But it is own
Object.hasOwn(o, "h")
Returns
true

Pitfalls

1. A false answer is ambiguous
It conflates three situations — the property is absent, the property is inherited, or the property is own but non-enumerable. Code that branches on false cannot tell which, so the two questions are better asked separately.
Same answer, different reasons
({}).propertyIsEnumerable("toString")
false — inherited
Be specific
Object.hasOwn(o, k) && Object.getOwnPropertyDescriptor(o, k).enumerable
each part separately
2. It is inherited, so it can be shadowed
Identical to hasOwnProperty and isPrototypeOf. An object from untrusted data, or one with a null prototype, breaks a direct call. ESLint no-prototype-builtins flags it for the same reason.
Missing
Object.create(null).propertyIsEnumerable("a")
TypeError: ...propertyIsEnumerable is not a function
Borrow it
Object.prototype.propertyIsEnumerable.call(o, "a")
false
3. There is no static form — and the obvious guess fails SILENTLY
Unlike hasOwnProperty, which gained Object.hasOwn in ES2022, this method has no static counterpart. Worse, writing Object.propertyIsEnumerable(o, k) does not throw: Object is itself an object, so it inherits the method, and the call runs with Object as the receiver and your object coerced to a string as the key. The answer is meaningless and always false.
Silently wrong
Object.propertyIsEnumerable({a: 1}, "a")
false // asks whether Object has "[object Object]"
Use a descriptor
Object.getOwnPropertyDescriptor(o, k)?.enumerable === true
works, and is unambiguous

When to use

Use it
  • Rarely — a compact own-and-enumerable test in code you control
  • Understanding why a property is missing from Object.keys
Reach for something else
  • You want to know if a property exists → Object.hasOwn
  • You want the enumerability specifically → getOwnPropertyDescriptor
  • You are listing keys → Object.keys already filters on this
  • Untrusted objects → the method may be shadowed or missing

Notes

Complexity
O(1) — one own-property lookup
Return
A boolean; nothing is allocated
CPython impl
V8: Builtins-object-propertyisenumerable
Memory
No allocation
Thread-safe
Single-threaded; the object is only read

FAQ

It adds the enumerability requirement. A property defined with defineProperty, or a built-in like array length, is an own property — so hasOwnProperty is true — but it is not enumerable, so this returns false.

const o = {};
Object.defineProperty(o, "h", {value: 1});
Object.hasOwn(o, "h");              // true
o.propertyIsEnumerable("h");        // false

History

ES3
propertyIsEnumerable present from early JavaScript with hasOwnProperty and isPrototypeOf.
ES5
The descriptor model made getOwnPropertyDescriptor a more informative alternative.