Skip to main content

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!