Object.getOwnPropertyDescriptor()
ES5+Returns a property descriptor for an own property of a given object.
Syntax
Object.getOwnPropertyDescriptor(obj, prop)Parameters
obj Object The object to look for the property on
prop string The name of the property whose descriptor should be retrieved
Return Value
A property descriptor of the given property, or undefined if it does not exist
Examples
const obj = { name: 'John' };
const desc = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(desc.value);
console.log(desc.writable); 📌 When to Use
Use Object.getOwnPropertyDescriptor() when you need to inspect property attributes, copy properties with their exact configurations, debug property behavior, or verify property definitions. Essential for metaprogramming and creating accurate object copies.
⚠️ Common Mistakes
Expecting it to return descriptors for inherited properties - it only works on own properties, not inherited ones.
Not checking for undefined return value - if the property does not exist, it returns undefined, not an error.
Forgetting that Symbol properties also have descriptors - use getOwnPropertyDescriptor with Symbol keys for complete inspection.
✅ Best Practices
Use Object.getOwnPropertyDescriptors() (plural) to get all property descriptors at once for efficient copying.
Combine with Object.defineProperties() for accurate property copying: Object.defineProperties({}, Object.getOwnPropertyDescriptors(source))
Create debugging utilities that display all property attributes in a readable format.
⚡ Performance Notes
Object.getOwnPropertyDescriptor() is an O(1) operation for looking up a single property descriptor. For getting all descriptors, use Object.getOwnPropertyDescriptors() which is more efficient than calling getOwnPropertyDescriptor in a loop. The returned descriptor is a new object, so modifications do not affect the original property.
🌍 Real World Example
Complete Object Cloning Utility
Create a utility that clones objects preserving all property attributes including getters, setters, and configurability.
function inspectProperty(obj, prop) {
const desc = Object.getOwnPropertyDescriptor(obj, prop);
if (!desc) return null;
return {
property: prop,
type: 'get' in desc ? 'accessor' : 'data',
value: desc.value,
hasGetter: !!desc.get,
hasSetter: !!desc.set,
writable: desc.writable,
enumerable: desc.enumerable,
configurable: desc.configurable
};
}
function cloneWithDescriptors(source) {
// Get the prototype
const proto = Object.getPrototypeOf(source);
// Create new object with same prototype and all property descriptors
return Object.create(
proto,
Object.getOwnPropertyDescriptors(source)
);
}
// Example: Object with getter/setter
const original = {
_value: 0,
get value() { return this._value; },
set value(v) { this._value = v; }
};
// Make _value non-enumerable
Object.defineProperty(original, '_value', { enumerable: false });
// Inspect properties
console.log(inspectProperty(original, 'value'));
// { property: 'value', type: 'accessor', hasGetter: true, hasSetter: true, enumerable: true, configurable: true }
console.log(inspectProperty(original, '_value'));
// { property: '_value', type: 'data', value: 0, writable: true, enumerable: false, configurable: true }
// Clone preserving all attributes
const clone = cloneWithDescriptors(original);
clone.value = 42;
console.log(clone.value); // 42
console.log(Object.keys(clone)); // ['value'] (_value is still non-enumerable)