Tutorial

The getOwnPropertyDescriptors Method in JavaScript

Guide to Object.getOwnPropertyDescriptors: how it works, examples with getters/setters, cloning objects while preserving accessors, differences with Object.assign, and a polyfill.

Drake Nguyen

Founder · System Architect

3 min read
The getOwnPropertyDescriptors Method in JavaScript
The getOwnPropertyDescriptors Method in JavaScript

What is Object.getOwnPropertyDescriptors?

Object.getOwnPropertyDescriptors is an ES2017 API that returns the full set of JavaScript property descriptors for all own properties of an object. Unlike Object.getOwnPropertyDescriptor (singular), which returns the descriptor for one property, this method produces an object mapping each property name to its descriptor. That makes it ideal when you need to inspect or copy getters and setters JavaScript or other descriptor attributes (enumerable, configurable, writable).

How to use Object.getOwnPropertyDescriptors in JavaScript

Use this method whenever you need accurate information about an object’s properties or when you want to clone an object while preserving accessor descriptors. Typical steps are:

  • Call Object.getOwnPropertyDescriptors(source) to obtain descriptors.
  • Apply those descriptors to a new object with Object.defineProperties(target, descriptors).

Object.getOwnPropertyDescriptors example with getters and setters

Example showing a property defined with a getter and a setter, then cloning the object while preserving accessors:

const animal = {
  name: 'Ben',
  type: 'reptilian',
  get fullName() {
    return `${this.name} ${this.type}`;
  },
  set animalName(n) {
    this.name = n;
  }
};

// Using Object.assign (cloning objects JavaScript)
const cloneAssign = Object.assign({}, animal);
// cloneAssign.fullName is now a normal value, not an accessor

// Preserving getters and setters
const cloneWithAccessors = Object.defineProperties(
  {},
  Object.getOwnPropertyDescriptors(animal)
);
// cloneWithAccessors.fullName remains a getter

Why Object.assign loses getters and setters

Object.assign copies enumerable own properties by reading their values. That reads a getter and writes the returned value into the target as a data property, so the accessor semantics are lost. By contrast, using Object.getOwnPropertyDescriptors and Object.defineProperties copies the descriptors themselves, keeping accessor descriptors (get/set) intact.

Difference between Object.getOwnPropertyDescriptors and Object.getOwnPropertyDescriptor

  • Object.getOwnPropertyDescriptor(obj, prop) - returns the descriptor for a single property.
  • Object.getOwnPropertyDescriptors(obj) - returns descriptors for all own properties at once, which is more convenient for cloning or bulk inspection.

Cloning objects while preserving descriptors

To clone an object and preserve getters, setters, and other descriptor attributes, combine the two APIs:

const clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(original));

Note: this preserves property descriptors for the first level of properties. For a true deep clone that preserves accessors at every level you must recursively copy nested objects and arrays rather than relying on this single-step approach.

Deep clone using Object.getOwnPropertyDescriptors and Object.defineProperties

A simple pattern for a recursive clone that preserves descriptors for nested plain objects:

function cloneWithDescriptors(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  const proto = Object.getPrototypeOf(obj);
  const descriptors = Object.getOwnPropertyDescriptors(obj);

  for (const key of Object.keys(descriptors)) {
    const desc = descriptors[key];
    if ('value' in desc && typeof desc.value === 'object' && desc.value !== null) {
      desc.value = cloneWithDescriptors(desc.value);
    }
  }

  return Object.create(proto, descriptors);
}

Practical tips and related keywords

  • Use Object.getOwnPropertyDescriptors when you need to copy descriptors including getters and setters JavaScript.
  • When performance matters and you only need values, Object.assign is simpler but it won’t preserve accessor semantics.
  • If you need compatibility, a lightweight Object.getOwnPropertyDescriptors polyfill can be implemented with Object.keys and Object.getOwnPropertyDescriptor.

Polyfill for getOwnPropertyDescriptors

if (!Object.getOwnPropertyDescriptors) {
  Object.getOwnPropertyDescriptors = function (obj) {
    const result = {};
    for (const key of Object.keys(obj)) {
      result[key] = Object.getOwnPropertyDescriptor(obj, key);
    }
    return result;
  };
}
Remember: Object.getOwnPropertyDescriptors is an ES2017 feature that gives you full control over property attributes—use it when cloning objects JavaScript or when you must preserve accessors.

Further reading ideas

  • Compare Object.defineProperty vs Object.defineProperties for defining single vs multiple descriptors.
  • Explore the attributes: enumerable, writable, configurable, and accessor vs data descriptors.
  • Research best practices for deep cloning and when to use descriptor-preserving strategies.

Stay updated with Netalith

Get coding resources, product updates, and special offers directly in your inbox.