Property Descriptors and Object.defineProperty

Difficulty: Advanced

Question

What are property descriptors in JavaScript? How does Object.defineProperty work?

Answer

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.

Code examples

Data Descriptor and Non-enumerable Properties

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.

Accessor Descriptors (Getters and Setters)

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.

Key points

Concepts covered

Property Descriptor, Object.defineProperty, writable, enumerable, configurable