Skip to main content

The writable, enumerable and configurable flags

The writable, enumerable and configurable flags are three service parameters inside a property descriptor that control how an object's properties behave in JavaScript. They are invisible during everyday work with an object, yet they are what decides whether a property can be changed, deleted or enumerated.

Theory

TL;DR

FlagWhat it doesDefault
writableAllows the property value to be changedfalse (when the property is created through defineProperty)
enumerableMakes the property visible during enumeration (for...in, Object.keys)false
configurableAllows the property to be deleted and its flags changedfalse
  • A plain assignment obj.key = value creates a property with all flags set to true.
  • You read the flags with Object.getOwnPropertyDescriptor(obj, key).
  • You can only set them through Object.defineProperty(obj, key, descriptor).

Quick example

javascript
const user = {}; Object.defineProperty(user, 'name', { value: 'Alice', writable: false, // cannot be changed enumerable: false, // does not appear in loops configurable: false // cannot be deleted, flags cannot be changed }); console.log(user.name); // "Alice" user.name = 'Bob'; // does not change delete user.name; // is not deleted console.log(Object.keys(user)); // [] because the property is not enumerated

writable: can the value be changed

javascript
const user = {}; Object.defineProperty(user, 'age', { value: 25, writable: false }); user.age = 30; // will not work console.log(user.age); // 25
  • writable: true allows the value to be changed;
  • writable: false makes the property read only.

In sloppy mode a write to such a property is silently ignored, in strict mode it throws a TypeError.

enumerable: is the property shown during enumeration

javascript
const user = {}; Object.defineProperty(user, 'secret', { value: '12345', enumerable: false }); console.log(user.secret); // readable directly console.log(Object.keys(user)); // [] because the property is invisible for (const key in user) console.log(key); // prints nothing
  • enumerable: true makes the property visible to for...in, Object.keys(), JSON.stringify();
  • enumerable: false makes it a hidden property.

A real world example: built-in methods (toString, valueOf) have enumerable: false so that they do not get in the way while iterating.

configurable: can it be deleted or its flags changed

javascript
const user = {}; Object.defineProperty(user, 'id', { value: 10, configurable: false }); delete user.id; // will not be deleted console.log(user.id); // 10 // Let us try to change writable: Object.defineProperty(user, 'id', { writable: true }); // TypeError: Cannot redefine property: id
  • configurable: true allows the property to be deleted or its flags changed;
  • configurable: false forbids deletion and any change to enumerable, configurable, or moving writable from false to true.

The one thing you can still change on such a property is writable from true to false, but not the other way round.

How to read and how to set the flags

Reading:

javascript
const obj = { name: 'Alice' }; const descriptor = Object.getOwnPropertyDescriptor(obj, 'name'); console.log(descriptor);

Prints:

javascript
{ value: 'Alice', writable: true, enumerable: true, configurable: true }

Setting:

javascript
Object.defineProperty(obj, 'prop', { value: 42, writable: false, enumerable: true, configurable: false });

Summary:

FlagPurposeExample
writableWhether the property value can be changeduser.age = 30
enumerableWhether the property is visible while iteratingObject.keys(user)
configurableWhether the property can be deleted or redefineddelete user.prop

Common mistakes

  • Forgetting that defineProperty sets every flag to false. A property created without an explicit enumerable: true vanishes from Object.keys() and from the JSON.stringify() output.
  • Expecting an error when writing to a writable: false property. Without 'use strict' the assignment silently fails and the bug is noticed late.
  • Confusing writable: false with an immutable object. If the property holds an object, its fields can still be changed; deep freezing means Object.freeze over the whole tree.
  • Counting on turning configurable back to true. It is a one way operation, so think first about which properties really need to be sealed.
  • Believing enumerable: false hides data. The property is still readable directly and still visible to Object.getOwnPropertyNames() and Reflect.ownKeys().
  • Using spread or Object.assign to copy. They carry over only enumerable own properties and lose the flags; an exact copy needs Object.getOwnPropertyDescriptors and Object.defineProperties.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.