What do you know about descriptors?
sobes.tech AI
Answer from AI
Descriptors in JavaScript are objects that describe various attributes of an object property, such as its value, writability, enumerability, and configurability. There are also descriptors with getters and setters.
There are two types of descriptors:
-
Data descriptors: Contain the value of the property.
value: The value of the property. Can be any valid data type.writable: A boolean indicating if the property value can be changed (obj.prop = newValue). Defaults tofalsefor accessor properties andtruefor data properties created by simple assignment.enumerable: A boolean indicating if the property will be visible during property enumeration (e.g., infor...inloops orObject.keys()). Defaults tofalsefor properties added withObject.defineProperty, andtruefor properties created by simple assignment.configurable: A boolean indicating if the property attributes can be changed and if the property can be deleted. Defaults tofalsefor properties added withObject.defineProperty(exceptvalue), andtruefor properties created by simple assignment. Once set as non-configurable, it cannot be changed back. You can decrease writability from true to false, but not vice versa on a non-configurable getter/setter.
-
Accessor descriptors: Define functions that are called when getting or setting the property value.
get: A function called when reading the property. Its result becomes the property value. It takes no arguments.set: A function called when writing to the property. It takes one argument — the new value.enumerable: A boolean (same as data descriptors).configurable: A boolean (same as data descriptors).
Descriptors cannot be mixed: a property either has value and writable, or get and set.
Descriptors are used for lower-level property management than simple assignment, especially through methods like Object.defineProperty(), Object.defineProperties(), Object.getOwnPropertyDescriptor(), Object.getOwnPropertyDescriptors(), Object.create().
Example of creating a property with a data descriptor:
// Create an empty object
const obj = {};
// Define a 'name' property with a data descriptor
Object.defineProperty(obj, 'name', {
value: 'Alice',
writable: false, // Property cannot be changed
enumerable: true, // Property will be enumerable
configurable: false // Property attributes cannot be changed, property cannot be deleted
});
console.log(obj.name); // Outputs: Alice
// Attempt to change the property (ignored in strict mode or throws an error)
obj.name = 'Bob';
console.log(obj.name); // Outputs: Alice
// Attempt to delete the property (ignored or throws an error)
delete obj.name;
console.log(obj.name); // Outputs: Alice
Example of creating a property with an accessor descriptor:
// Create an object with private variables
const user = {
_firstName: 'John', // Private variable by convention
_lastName: 'Doe'
};
// Define a 'fullName' property with accessor descriptors
Object.defineProperty(user, 'fullName', {
get() {
// Getter: returns the full name
return `${this._firstName} ${this._lastName}`;
},
set(value) {
// Setter: splits the full name into parts and updates private variables
const parts = value.split(' ');
this._firstName = parts[0];
this._lastName = parts[1];
},
enumerable: true, // Property will be enumerable
configurable: true // Property attributes can be changed, property can be deleted
});
console.log(user.fullName); // Outputs: John Doe
user.fullName = 'Peter Pan';
console.log(user._firstName); // Outputs: Peter
console.log(user._lastName); // Outputs: Pan
console.log(user.fullName); // Outputs: Peter Pan
Using descriptors allows creating immutable properties, lazily computed properties, access-controlled properties (getters/setters), and more flexible object behavior.