This chapter follows Objects in JavaScript.
Assignment (obj.key = value) creates or updates an own property with default descriptor flags. When you need getters, setters, non-enumerable fields, or immutability guarantees at the property level, use Object.defineProperty (or Reflect.defineProperty) with an explicit property descriptor.
Object.defineProperty(obj, prop, descriptor);Data descriptor vs accessor descriptor
A data descriptor has a value and optional writable. An accessor descriptor has get and/or set functions. A descriptor must be one flavor, not both; mixing value with get throws.
const obj = {};Object.defineProperty(obj, 'key2', { configurable: false, enumerable: false, value: 'static', writable: false,});
const tracked = {};let bValue = 38;Object.defineProperty(tracked, 'b', { get() { return bValue; }, set(newValue) { bValue = newValue; }, enumerable: true, configurable: true,});Descriptor attributes
| Key | Meaning | Default with defineProperty |
Default with { key: val } |
|---|---|---|---|
configurable |
If false, delete and further descriptor changes are forbidden (with narrow exceptions) | false | true |
enumerable |
Appears in for...in, Object.keys, spread/Object.assign |
false | true |
value |
Stored value for data descriptors | undefined | — |
writable |
Assignment can change value |
false | true |
get / set |
Accessor functions | undefined | — |
If a descriptor omits value, writable, get, and set, it is treated as a data descriptor. Check enumerability with obj.propertyIsEnumerable('a').
More examples: MDN: Object.defineProperty.
Object descriptors in decorators
Object descriptors are the same objects TypeScript experimental decorators receive when they wrap class fields or methods—the decorator mutates or replaces the descriptor before the property is installed.