The Object propertyIsEnumerable() method

By

Learn how the JavaScript propertyIsEnumerable() method checks whether a property exists on an object and is enumerable, returning true or false.

~~~

The propertyIsEnumerable() method tells you if a property of an object is enumerable. Called on an object instance, it accepts a string as argument. If the object has an own property with that name, and that property is enumerable, it returns true. Otherwise it returns false.

An enumerable property is one that shows up when you loop over an object. for...in loops, Object.keys(), and the spread operator all only see enumerable properties.

Properties you create with a normal assignment are enumerable by default. Properties can be made non-enumerable with Object.defineProperty(), which is how you hide internal values from loops and serialization.

Example:

const person = { name: 'Fred' }

Object.defineProperty(person, 'age', {
  value: 87,
  enumerable: false
})

person.propertyIsEnumerable('name') //true
person.propertyIsEnumerable('age') //false

Both properties exist on the object. You can read person.age and get 87. But age was defined as non-enumerable, so it’s invisible to Object.keys(person), and propertyIsEnumerable() reports that.

If the property doesn’t exist at all, you also get false:

person.propertyIsEnumerable('email') //false

When would you use it?

You reach for this method when you need to know whether a property will show up in iteration. Say you’re writing a function that copies an object’s data. Loops and spread skip non-enumerable properties, so propertyIsEnumerable() lets you predict what will be copied and what will be left behind.

You’ll also see it used to inspect built-in objects. Array indexes are enumerable, but length is not:

const list = ['a', 'b']
list.propertyIsEnumerable(0) //true
list.propertyIsEnumerable('length') //false

This is why looping over an array gives you the items, and never the length property.

It only checks own properties

Here’s the pitfall. propertyIsEnumerable() returns false for inherited properties, even if they are enumerable on the prototype:

const settings = Object.create({ theme: 'dark' })
settings.fontSize = 16

settings.propertyIsEnumerable('fontSize') //true
settings.propertyIsEnumerable('theme') //false
'theme' in settings //true

The theme property is there, the in operator confirms it, but it lives on the prototype. If you need to check inherited properties too, walk the prototype chain with Object.getPrototypeOf() and repeat the check there.

~~~

Related posts about js: