Difficulty: Advanced
What are property descriptors in JavaScript? How does Object.defineProperty work?
Every object property has a descriptor that controls its behavior. There are two types:
Data descriptor: { value, writable, enumerable, configurable } Accessor descriptor: { get, set, enumerable, configurable }
Flags: - writable: can the value be changed? - enumerable: does it appear in for...in or Object.keys()? - configurable: can the descriptor itself be changed or the property deleted?
Properties created with assignment default to all flags true; properties created with defineProperty default to all flags false.
const obj = {};
Object.defineProperty(obj, 'PI', {
value: 3.14159,
writable: false,
enumerable: true,
configurable: false
});
obj.PI = 999;
console.log(obj.PI);
Object.defineProperty(obj, '_secret', {
value: 'hidden',
enumerable: false,
writable: true,
configurable: true
});
console.log(Object.keys(obj));
console.log(obj._secret);
console.log(Object.getOwnPropertyDescriptor(obj, 'PI'));
writable: false prevents assignment. enumerable: false hides from Object.keys() but the property is still accessible directly.
const temperature = {};
let _celsius = 0;
Object.defineProperty(temperature, 'celsius', {
get() { return _celsius; },
set(val) {
if (val < -273.15) throw new RangeError('Below absolute zero');
_celsius = val;
},
enumerable: true,
configurable: true
});
Object.defineProperty(temperature, 'fahrenheit', {
get() { return _celsius * 9/5 + 32; },
set(val) { _celsius = (val - 32) * 5/9; },
enumerable: true,
configurable: true
});
temperature.celsius = 100;
console.log(temperature.fahrenheit);
temperature.fahrenheit = 32;
console.log(temperature.celsius);
Accessor descriptors allow computed properties and validation. The get/set functions run transparently on access and assignment.
Property Descriptor, Object.defineProperty, writable, enumerable, configurable