What are JavaScript object property flags and descriptors?
TL;DR
In JavaScript, property flags and descriptors manage the behavior and attributes of object properties.
Property flags
Property flags are used to specify the behavior of a property on an object. Here are the available flags:
writable
: Specifies whether the property can be written to. Defaults totrue
.enumerable
: Specifies whether the property is enumerable. Defaults totrue
.configurable
: Specifies whether the property can be deleted or its attributes changed. Default istrue
.
Property descriptors
These provide detailed information about an object's property, including its value and flags. They are retrieved using Object.getOwnPropertyDescriptor()
and set using Object.defineProperty()
.
The use cases of property descriptors are as follows:
- Making a property non-writable by setting
writable: false
to ensure data consistency. - Hiding a property from enumeration by setting
enumerable: false
. - Preventing property deletion and modification by setting
configurable: false
. - Freezing or sealing objects to prevent modifications globally.
JavaScript object property flags and descriptors
In JavaScript, property flags and descriptors are used to manage the behavior and attributes of object properties. These flags and descriptors are essential for understanding how properties are accessed, modified, and inherited.
Property flags
Property flags are used to specify the behavior of a property. They are set using the Object.defineProperty()
method, which allows you to define a property on an object with specific attributes. The available property flags are:
writable
: Specifies whether the property can be written to. Defaults totrue
.enumerable
: Specifies whether the property is enumerable. Defaults totrue
.configurable
: Specifies whether the property can be deleted or its attributes changed. Default istrue
.
Property descriptors
Property descriptors provide detailed information about an object's property, encapsulating its value and flags. They are retrieved using Object.getOwnPropertyDescriptor()
and set using Object.defineProperty()
let user = { name: 'John Doe' };let descriptor = Object.getOwnPropertyDescriptor(user, 'name');console.log(descriptor); // {value: "John Doe", writable: true, enumerable: true, configurable: true}
Manipulating property flags
writable
flag
The writable
flag specifies whether a property can be written to. When writable
is false
, trying to assign value to the property fails silently in non-strict mode, and it throws a TypeError
in strict mode.
const obj = {};Object.defineProperty(obj, 'name', {writable: false,value: 'John Doe',});console.log(obj.name); // Output: John Doeobj.name = 'Jane Doe'; // TypeError: Cannot assign to read only property 'name' of object '#<Object>'
enumerable
flag
The enumerable
flag specifies whether a property is enumerable. The enumerable flag
is set to true
, which means the property is visible in a for...in
loop.
const obj = {};Object.defineProperty(obj, 'name', {enumerable: false,value: 'John Doe',});for (const prop in obj) {console.log(prop); // Output: nothing}const obj1 = {};Object.defineProperty(obj1, 'name', {enumerable: true,value: 'John Doe',});for (const prop in obj1) {console.log(prop); // Output: name}
configurable
flag
The configurable
flag specifies whether a property can be deleted or its attributes changed. When configurable
is false
, trying to delete or change the property fails silently in non-strict mode, and it throws a TypeError
in strict mode.
const obj = {};Object.defineProperty(obj, 'name', {configurable: false,value: 'John Doe',});delete obj.name; // Output: TypeError: Cannot delete property 'name' of #<Object>
Object.seal()
The Object.seal()
method in JavaScript effectively prevents the addition or removal of properties from the object, while still allowing the modification of existing property values. It also makes all properties non-configurable, meaning their descriptors (like writable
, enumerable
, and configurable
) cannot be changed.