The function Object.getOwnPropertyDescriptors
is in the ECMAScript latest draft specification, but is implemented in popular browsers. It returns the property descriptors belonging to an object.
Your use-case is a bit more difficult because the getter is defined on the class, not the object itself. So, you need to walk the prototype chain and build it that way. It's not enough to look at just the object's prototype, because the getter could be inherited from any superclass of the object's class.
Here's a recursive function which does it:
function getAllPropertyDescriptors(obj) {
if (!obj) {
return Object.create(null);
} else {
const proto = Object.getPrototypeOf(obj);
return {
...getAllPropertyDescriptors(proto),
...Object.getOwnPropertyDescriptors(obj)
};
}
}
The output for JSON.stringify(getAllPropertyDescriptors(thing))
is below. myGetter
is the third property descriptor; the actual output if you don't JSON.stringify it also includes references to the actual functions, so you can see if they have get
/set
properties.
{
"myProperty": {"value": 22, "writable": true, "enumerable": true, "configurable": true},
"constructor": {"writable": true, "enumerable": false, "configurable": true},
"myGetter": {"enumerable": false, "configurable": true},
"__defineGetter__": {"writable": true, "enumerable": false, "configurable": true},
"__defineSetter__": {"writable": true, "enumerable": false, "configurable": true},
"hasOwnProperty": {"writable": true, "enumerable": false, "configurable": true},
"__lookupGetter__": {"writable": true, "enumerable": false, "configurable": true},
"__lookupSetter__": {"writable": true, "enumerable": false, "configurable": true},
"isPrototypeOf": {"writable": true, "enumerable": false, "configurable": true},
"propertyIsEnumerable": {"writable": true, "enumerable": false, "configurable": true},
"toString": {"writable": true, "enumerable": false, "configurable": true},
"valueOf": {"writable": true, "enumerable": false, "configurable": true},
"__proto__": {"enumerable": false, "configurable": true},
"toLocaleString": {"writable": true, "enumerable": false, "configurable": true}
}
You could convert this into an iterative version, but that's probably unnecessary since most prototype chains are short, and the iterative version would need some wrangling to get overrides in the right order.