It’s been a while since I needed to list a JavaScript object’s methods at runtime, but I needed to do it recently. I tried what I thought I used to do: no luck. So I looked on google; checked with chatGPT; and looked on StackOverflow. Most of what I found was along the lines of
const methodNames = Object.getOwnPropertyNames(obj)
.filter(function(property) {
return typeof obj[property] == 'function';
});
That’s how I used to do it. But that’s when I worked with prototypes, not classes. If the object was created with “new ClassName()” the methods are in the object’s prototype, not the object itself. It’s a pretty easy change. Instead of getting property names from the object, get them from the object’s prototype:
const methodNames =
Object.getOwnPropertyNames(Object.getPrototypeOf(obj))
.filter(function(property) {
return typeof obj[property] == 'function';
});
What About …
What if the object wasn’t created with new?
const obj = {name:"fred", getName:function() {return this.name;}}
What if additional methods were added after creation?
const obj = new Person("fred");
obj.getName = function() { return this.name;}
What if the class extends another class (and that one extends…)?
The simple solution above misses those cases. But it’s not a lot more effort to collect all methods regardless of how they became part of the object. I wrote a function to do that
function getMethods(object) {
const methods = new Map();
let proto = object;
while (proto != null && proto.constructor != Object) {
for (let name of Object.getOwnPropertyNames(proto)) {
const value = proto[name];
if (isFunction(value) && methods[name] == null) {
methods.set(name, value);
}
}
proto = Object.getPrototypeOf(proto);
}
return methods;
}
The first time through the while() it treats the object itself as the property source. It collects all properties that are functions.
Then it gets the object’s prototype, using getPrototypeOf() and goes through the while again, but this time if the function name already exists it is not included. This happens if a function with the same name was added after “new”.
Then it gets the prototype of the prototype. If the class extended another class, it has a prototype with methods of the superclass. This is repeated until it reaches the prototype of the Object class.
Object is the final superclass for all other classes. In my case, I do not want to include methods of class Object so I stop when I reach this. The way to detect if the prototype is of Object is using the constructor
proto.constructor != Object
Instead of returning an array of functions, I return a Map of function names to functions

The values are functions in the prototype, not bound to the specific object instance. You will need call(), apply(), bind() or another mechanism to invoke the function with the correct “this” value.