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!

Psalm 147:4-5 (SDG)

About the author

My name is Sean McPherson, and I am a software engineer interesed in all areas of front-end development. Here I write articles about programming for developers of all levels, and occassionally other topics.

Currently I work for Niche.com and live with my lovely family in Pittsburgh, PA.