Static Methods vs. Instance Methods in JavaScript Classes

Hero image for Static Methods vs. Instance Methods in JavaScript Classes. Image by Jonathan Wuyts.
Hero image for 'Static Methods vs. Instance Methods in JavaScript Classes.' Image by Jonathan Wuyts.

Once developers are comfortable with JavaScript class syntax, a more practical design question usually follows:

Should this method live on the class itself, or on each instance?

That is the difference between static methods and instance methods.

It is not only a syntax detail. It affects how the API reads, what data the method can access, and whether the class design stays intuitive as it grows.


Instance Methods Belong to Objects Created from the Class

If we define a method normally inside a class, instances can call it:

class User {  constructor(public firstName: string, public lastName: string) {}  getFullName(): string {    return `${this.firstName} ${this.lastName}`;  }}const user = new User('Ellie', 'Nguyen');console.log(user.getFullName());

getFullName() is an instance method because it operates on the data stored in a particular user object.

That is the key clue. Instance methods usually need this.


Static Methods Belong to the Class Itself

If we add the static keyword, the method is called on the class rather than an instance:

class User {  constructor(public firstName: string, public lastName: string) {}  static createGuest(): User {    return new User('Guest', 'User');  }}const guest = User.createGuest();

Now the method lives on User, not on guest.

This is why the following would fail:

guest.createGuest();

Static methods are not copied onto each instance.


The Simplest Decision Rule

Ask this question:

Does the method need to work with a specific instance's state?

If yes, it is probably an instance method.

If no, and it belongs conceptually to the class as a type or factory, it may be a good candidate for a static method.


Instance Methods Describe Object Behaviour

These are often the methods that read like verbs attached to a particular thing:

class Cart {  constructor(public items: string[] = []) {}  addItem(item: string): void {    this.items.push(item);  }  getItemCount(): number {    return this.items.length;  }}

Both methods rely on the state of one particular cart.

That makes them instance methods almost by definition.


Static Methods Often Work Well as Factory Helpers

This is one of the nicest uses of the feature.

For example:

class User {  constructor(public firstName: string, public lastName: string) {}  static fromApi(data: {    first_name: string;    last_name: string;  }): User {    return new User(data.first_name, data.last_name);  }}

fromApi() is not about one existing user instance. It is about creating a user instance from some external data shape.

That makes it feel much more natural as a static method than as an instance method.


Sometimes a helper is tightly related to the concept represented by the class, but does not belong to a specific object:

class Temperature {  static fromFahrenheit(value: number): number {    return (value - 32) * (5 / 9);  }}

You could write a standalone function instead. That is also valid.

The benefit of a static method is that it keeps the utility attached to the domain concept in a discoverable way.


A Common Mistake is Trying to Access Instance State from a Static Method

This catches people quickly:

class User {  constructor(public firstName: string) {}  static greet(): string {    return `Hello, ${this.firstName}`;  }}

That does not do what many beginners expect, because in a static method this refers to the class itself, not an instance created from it.

If the method needs instance data, it should not be static.


The opposite Mistake Happens Too

Some methods are placed on instances even though they do not use instance state at all:

class User {  formatName(firstName: string, lastName: string): string {    return `${firstName} ${lastName}`;  }}

That forces callers to create a User instance just to use a general helper, which is usually a sign the method is in the wrong place.

It might belong:

  • as a static method
  • as a plain standalone function

The right answer depends on whether the logic truly belongs to the class concept.


Good Class Apis Usually Make the Distinction Feel Obvious

When the design is clean, the method placement reads naturally.

Instance methods feel like behaviour of a thing:

user.getFullName();cart.addItem('Notebook');

Static methods feel like behaviour of the type:

User.createGuest();User.fromApi(payload);

That difference in call site readability matters more than people sometimes admit.


Static Methods are Not Automatically "Better Organised"

There is a temptation to push lots of unrelated helpers into classes as static methods because it feels tidy.

But a class full of static utilities can easily become a namespace in disguise rather than a wellshaped model.

So the real test is not whether a method can be made static. It is whether making it static improves the meaning of the API.


Inheritance Affects Static Methods Too

One subtle point worth knowing is that static methods are inherited by subclasses as well.

That can be useful for factory patterns, though it also means class hierarchies can become more complex if too many responsibilities are piled into static APIs.

You do not need to memorise every edge of that immediately. The important part is simply knowing that static behaviour is part of the class system, not a separate random feature.


The Real Question is Where the Behaviour Belongs

That is the theme behind all of this.

If the method answers a question about one object, or changes that object's data, make it an instance method.

If the method creates instances, transforms external input into instances, or offers classlevel behaviour that does not depend on one object's state, a static method may fit well.

When that distinction is respected, classbased APIs stay much easier to read and maintain.


Static and Instance Methods are Both Useful for Different Reasons

This is not a contest where one style wins.

Instance methods make objects feel alive and coherent.

Static methods make classlevel helpers and factories discoverable.

The trick is simply to put each piece of behaviour in the place that reflects what it actually depends on. Once you do that, the syntax stops being the interesting part, and the class design starts making sense.


Categories:

  1. Development
  2. Front‑End Development
  3. Guides
  4. JavaScript