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
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.getOwnPropertyDescriptorswhen you need to copy descriptors including getters and setters JavaScript. - When performance matters and you only need values,
Object.assignis simpler but it won’t preserve accessor semantics. - If you need compatibility, a lightweight
Object.getOwnPropertyDescriptors polyfillcan be implemented withObject.keysandObject.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.definePropertyvsObject.definePropertiesfor 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.