The Object getOwnPropertyDescriptor() method
By Flavio Copes
Learn how the JavaScript Object.getOwnPropertyDescriptor() method returns the descriptor of a property, with its value, writable, enumerable, and configurable.
Object.getOwnPropertyDescriptor() returns the descriptor of a specific property: its value, plus the flags that control how the property behaves.
Usage:
const propertyDescriptor = Object.getOwnPropertyDescriptor(object, propertyName)
Example:
const dog = {}
Object.defineProperties(dog, {
breed: {
value: 'Siberian Husky'
}
})
Object.getOwnPropertyDescriptor(dog, 'breed')
/*
{
value: 'Siberian Husky',
writable: false,
enumerable: false,
configurable: false
}
*/
What is a property descriptor?
Every property of an object carries hidden metadata along with its value:
writable: can the value be changed?enumerable: does the property show up infor...inloops and inObject.keys()?configurable: can the property be deleted, or its flags changed?
Normally you never see these flags. getOwnPropertyDescriptor() is how you inspect them.
Why are all the flags false in the example?
Because the property was created with Object.defineProperties(), and every flag you don’t specify there defaults to false.
Properties created with a plain assignment get the opposite defaults:
const cat = {}
cat.breed = 'Maine Coon'
Object.getOwnPropertyDescriptor(cat, 'breed')
/*
{
value: 'Maine Coon',
writable: true,
enumerable: true,
configurable: true
}
*/
This makes the dog example above effectively read-only. Since writable is false, assigning a new breed fails silently, or throws in strict mode.
Getters and setters look different
For an accessor property, the descriptor contains get and set functions instead of value and writable:
const person = {
get name() {
return 'Flavio'
}
}
Object.getOwnPropertyDescriptor(person, 'name')
/*
{
get: [Function: get name],
set: undefined,
enumerable: true,
configurable: true
}
*/
Watch out for inherited properties
The “own” in the name matters. The method only looks at properties directly on the object. For inherited ones, it returns undefined:
const dog = { breed: 'Siberian Husky' }
Object.getOwnPropertyDescriptor(dog, 'toString') //undefined
You can call dog.toString(), but the method lives on Object.prototype, so it’s not an own property of dog. If you get undefined for a property you can clearly access, check whether it’s inherited.
To get the descriptors of all own properties in one call, use Object.getOwnPropertyDescriptors() (plural). It returns an object with one descriptor per property name.
When is this useful?
The main use case is copying properties without losing their nature. Object.assign() calls getters and copies the resulting values. Copying the descriptor with Object.defineProperty() instead preserves the getter itself, along with all the flags.
Related posts about js: