Count class methods in JavaScript
If you have a class in JavaScript and want to know the number of methods it contains, there are a few steps that you need to follow.
Let's say we have a class like the following:
class Pet {
constructor(name) {
this.name = name;
}
call() {
console.log(this.name + " comes running");
}
}
We don't have handy tools like Object.keys()
for classes, so to count the
number of methods in our Pet
class, we need to first create an instance:
const abby = new Pet("Abby");
Now we can pass our instance to two Object
methods that will grab the methods
for us:
Object.getOwnPropertyNames(Object.getPrototypeOf(abby));
This returns an array of property names for the prototype of abby
, which is
the following:
["constructor", "call"];
If you're dealing with a simple class like the example above, you can add a
.length
to the end of the returned array and be done.
However, if you are dealing with subclasses, you may want to go a little deeper.
Let's update the example so that the class who's methods you want to count extends another:
class Pet {
constructor(name) {
this.name = name;
}
call() {
console.log(this.name + " comes running");
}
}
class Dog extends Pet {
pet() {
console.log(`${this.name} wags its tail`);
}
}
Now if we try the following code with abby
the Dog
, we get a different
answer:
const abby = new Dog("Abby");
Object.getOwnPropertyNames(Object.getPrototypeOf(abby));
// ['constructor', 'pet']
We lost the methods on the parent Pet
class. To grab those too, we can create
a reusable function to dive through the prototype chain:
function countClassMethods(_class) {
const methods = new Set();
let keepDiving = true;
let prototype = Object.getPrototypeOf(_class);
while (keepDiving) {
Object.getOwnPropertyNames(prototype).forEach((name) => methods.add(name));
prototype = Object.getPrototypeOf(prototype);
if (!prototype.__proto__) keepDiving = false;
}
return methods.size;
}
This function takes a class and grabs its prototype. Then in a while
loop, it
iterates through the prototype's property names and adds them to a set. It then
looks ahead to the next prototype to determine whether it should continue. If
the next prototype's __proto__
property is falsy, then leave the loop and
return the size of the set.
If you want to see a list of the methods, you could rename the function and
return [...methods]
or do something with method.values()
.
Now when I call my function with an instance of the Dog
class, I get the
answer that I'm expecting:
const abby = new Dog("Abby");
countClassMethods(abby); // 3
// Values: ['constructor', 'pet', 'call']
This is a pretty niche scenario, but I hope that is helpful for someone else.
Happy counting!