The Object getOwnPropertyDescriptor() method

By

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:

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: