This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.
The handler.getOwnPropertyDescriptor() method is a trap for the [[GetOwnProperty]] object internal method, which is used by operations such as Object.getOwnPropertyDescriptor().
const monster = {
eyeCount: 4,
};
const handler = {
getOwnPropertyDescriptor(target, prop) {
console.log(`called: ${prop}`);
// Expected output: "called: eyeCount"
return { configurable: true, enumerable: true, value: 5 };
},
};
const proxy = new Proxy(monster, handler);
console.log(Object.getOwnPropertyDescriptor(proxy, "eyeCount").value);
// Expected output: 5
new Proxy(target, {
getOwnPropertyDescriptor(target, property) {
}
})
The following parameters are passed to the getOwnPropertyDescriptor() method. this is bound to the handler.
The getOwnPropertyDescriptor() method must return an object or undefined, representing the property descriptor. Missing attributes are normalized in the same way as Object.defineProperty().
This trap can intercept these operations:
Or any other operation that invokes the [[GetOwnProperty]] internal method.
The proxy's [[GetOwnProperty]] internal method throws a TypeError if the handler definition violates one of the following invariants:
Object or undefined.Reflect.getOwnPropertyDescriptor() returns configurable: false for the property on target, then the trap must not return undefined.Reflect.isExtensible() returns false for the target object, then the trap must not return undefined.Reflect.isExtensible() returns false for the target object, and Reflect.getOwnPropertyDescriptor() returns undefined for the property on target, then the trap must return undefined.Reflect.getOwnPropertyDescriptor() returns undefined or configurable: true for the property on target, then the trap must not return configurable: false.Reflect.getOwnPropertyDescriptor() returns configurable: false, writable: true for the property on target, then the trap must not return configurable: false, writable: false.descriptor. That is, pretending target is an ordinary object, then Object.defineProperty(target, property, resultObject) must not throw an error. The Object.defineProperty() reference contains more information, but to summarize, when the target property is non-configurable, the following must hold: configurable, enumerable, get, and set must be the same as original. writable must also be the original by virtue of the previous invariant.value attribute can only be changed if writable is true
The following code traps Object.getOwnPropertyDescriptor().
const p = new Proxy(
{ a: 20 },
{
getOwnPropertyDescriptor(target, prop) {
console.log(`called: ${prop}`);
return { configurable: true, enumerable: true, value: 10 };
},
},
);
console.log(Object.getOwnPropertyDescriptor(p, "a").value);
// "called: a"
// 10
The following code violates an invariant.
const obj = { a: 10 };
Object.preventExtensions(obj);
const p = new Proxy(obj, {
getOwnPropertyDescriptor(target, prop) {
return undefined;
},
});
Object.getOwnPropertyDescriptor(p, "a"); // TypeError is thrown
| Desktop | Mobile | Server | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android | WebView on iOS | Bun | Deno | Node.js | |
getOwnPropertyDescriptor |
49 | 12 | 18 | 36 | 10 | 49 | 18 | 36 | 10 | 5.0 | 49 | 10 | 1.0.0 | 1.0 | 6.0.0 |
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor