cf.completefrontendCode editorOpen lab
THE JAVASCRIPT FIELD GUIDE

Static members & static blocks

Learn how JavaScript class static fields, static methods, static initialization blocks, inherited statics, and factory methods put behavior on the class itself instead of each instance.

By the end, you can
  • 01
    Put data on the classUse static fields and methods for counters, registries, and utilities.
  • 02
    Trace class definition timePredict when static fields and static blocks run, and prove they run once.
  • 03
    Design clear factoriesWrite named constructors such as fromJSON and fromHex without overloading constructor.

Class-level members

A class usually teaches JavaScript how to build instances: one article, one color, one user, one ticket. A static member is different. It belongs to the class itself. You use it as ClassName.member, not as instance.member.

This connects back to Functions are objects: a class is a special kind of function, and functions can have properties. A static field is a property on that class function. A static method is a function stored there. The Class basics & extends lesson gives you the instance side; this lesson gives you the class side.

Real-life analogyStatics belong to the factory, not each product

Imagine a car factory. The factory keeps a production counter and a checklist for turning a serial number into a car. Each car keeps its own mileage and tire pressure. You would not store total cars built inside every car, and you would not store one car’s mileage on the factory wall. Static members are the factory wall.

In real life: The car factory's production counter
In JavaScript: Car.built static field
In real life: The factory's quality-check recipe
In JavaScript: Car.fromSerial(...) static factory
In real life: One car’s mileage
In JavaScript: car.mileage instance field
In real life: One car’s horn button
In JavaScript: car.honk() instance method

Where the analogy stops: A real factory and car are separate physical things. In JavaScript the class is also the constructor function used by new, so the factory and blueprint live in one value.

Class side vs instance side
QuestionStaticInstance
How you call itUser.create(raw)user.save()
Where it is foundOn the class constructor functionOn the object or its prototype
What this usually isThe class, such as UserOne object, such as user
Good forCounters, registries, parsers, factories, utilitiesBehavior that reads or changes one object’s state

In this lesson you will watch class setup run, count instances with a shared field, prove statics are inherited, and build named factory methods like Temperature.fromFahrenheit(98.6).

Static methods & fields

STEP THROUGH

Add the static keyword inside a class body to create a class-level field or method. The name is read from the class: Ticket.sold and Ticket.summary(). It is not copied onto ada or lin when you create tickets.

Count instances with a static field
Step 0 of 8Ready
Your turn: follow the blue line

Step through two instances. Watch one static field count both of them, then prove the method is not on either instance.

Running in
  1. script
Next: line 2
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
class Ticket {  constructor(name) {    this.name = name;    Ticket.sold += 1;  }  static summary() {    return Ticket.sold + " tickets sold";  }}const ada = new Ticket("Ada");const lin = new Ticket("Lin");console.log(Ticket.summary());console.log(ada.summary);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

The counter example shows the usual shape: a static field stores shared state, and a constructor or method updates it. The output also proves a common gotcha: ada.summary is undefined. If the member starts with static, call it on the class.

Static does not mean frozen

A static field can change. Ticket.sold starts at 0 and becomes 1, then 2. The word static means “on the class,” not “unchangeable.” Use readonly patterns, private fields, or conventions when you need protection.

Static methods are also useful when no instance is needed. JavaScript’s built-ins use this style all the time:

Built-in static-style callsPop out in the code editor (opens in a new tab)JavaScript
Math.max(3, 10);Date.parse("2026-09-25");Array.from("JS");Object.fromEntries([["role", "admin"]]);

Math.max is a Math-like utility: you never write new Math(). Array.from and Object.fromEntries are named entrances that create values from other shapes of data. That naming pattern becomes important when we reach factory methods.

Static or instance?
  • User.fromJSON(raw) parses data and returns a new user
  • user.fullName() reads this.firstName and this.lastName
  • Ticket.sold counts every ticket that has been constructed
  • car.mileage is different for every car
  • Plugin.registry stores plugins by name
  • article.render() uses this article's title and body
Try it yourself
0 of 6 correct

Decide whether each member belongs on the class or on one object. Ask: does it need one object’s state, or the whole class?

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Static initialization blocks

INTERACTIVE

Static fields handle simple setup. A static block handles setup that needs several statements: fill a registry, validate a table, connect related static fields, or choose a fallback. It runs while the class definition is evaluated, exactly once, before code after the class continues.

Real-life analogyA static block is opening-day setup

Before a factory makes its first product, someone opens the doors, calibrates machines, and writes the first checklist. That is not a per-product step. A static block is the class’s opening-day setup.

In real life: Unlock the factory and calibrate machines
In JavaScript: Run the static { ... } block
In real life: Write the initial production notes
In JavaScript: Fill class-level fields and registries
In real life: Build the first product later
In JavaScript: Call new ClassName(...) later

Where the analogy stops: Opening-day setup might involve people and clocks. A static block is deterministic code that runs as part of evaluating the class; it should not depend on browser-only values during server rendering.

Step through this recording slowly. Notice that the static block logs before after class definition, and before the constructor logs Ada #1.

Watch class setup run before instances
Step 0 of 9Ready
Your turn: follow the blue line

Before stepping, predict which message prints first. Static fields and blocks run while the class is defined, before any constructor call.

Running in
  1. script
Next: line 2
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
class Workshop {  static setupLog = [];  static {    Workshop.setupLog.push("factory setup");    console.log("static block ran");  }  constructor(name) {    this.name = name;    this.id = Workshop.nextId++;    console.log(name + " #" + this.id);  }}console.log("after class definition");const first = new Workshop("Ada");console.log(Workshop.setupLog.length);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Static fields and blocks run in the order they appear. A block can read earlier static fields and write later static fields once they exist, but the cleanest code puts fields first, then the block that prepares them. Avoid doing reader-specific work during render. If setup depends on window, locale formatting, random numbers, or time, compute it on the client after the page mounts or on a user action.

Inheriting statics

STEP THROUGH

extends links two sides at once. Instances of Sub can find methods from Base.prototype, and the subclass constructor Sub can find static members on Base. That is why Object.getPrototypeOf(Sub) === Base is true.

Inherited statics keep the subclass as this
Step 0 of 6Ready
Your turn: follow the blue line

Predict the three printed values. The key question: when a subclass calls an inherited static method, what is this?

Running in
  1. script
Next: line 10
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
class BaseModel {  static create(name) {    console.log(this.name);    return new this(name);  }  constructor(name) {    this.name = name;  }}console.log(Object.getPrototypeOf(User) === BaseModel);const user = User.create("Ada");console.log(user instanceof User);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

The important part is this. Inside a static method, this is the class used for the call. When you call User.create("Ada"), the inherited method runs with this === User. That lets the base method return new this(name), so subclasses get instances of themselves.

Private statics are next

Public inherited statics are covered here. Private static fields and methods use # names and have stricter access rules. The next lesson, Private fields & methods, covers that carefully.

Factory methods

INTERACTIVE

JavaScript does not support multiple constructors with different names. A class has one constructor. Static factory methods give you named entrances instead. The name tells readers what kind of input they are handing over.

A named entrance says what the number meansPop out in the code editor (opens in a new tab)JavaScript
class Temperature {  constructor(celsius) {    this.celsius = celsius;  }  static fromFahrenheit(value) {    return new Temperature((value - 32) * 5 / 9);  }}const normal = Temperature.fromFahrenheit(98.6);

new Temperature(98.6) is ambiguous: is that Celsius or Fahrenheit? Temperature.fromFahrenheit(98.6) says exactly what the input means. Factories can validate input, normalize data, choose a subclass, use a cache, or return an existing instance.

Factory methods: choose the entrance
Color with named factoriesPop out in the code editor (opens in a new tab)JavaScript
class Color {  constructor(red, green, blue) {    this.red = red;    this.green = green;    this.blue = blue;  }  static fromHex(hex) {    if (!/^#[0-9a-f]{6}$/i.test(hex)) throw new Error("Use #RRGGBB");    return new Color(      parseInt(hex.slice(1, 3), 16),      parseInt(hex.slice(3, 5), 16),      parseInt(hex.slice(5, 7), 16)    );  }  static fromRGB(red, green, blue) {    for (const value of [red, green, blue]) {      if (!Number.isInteger(value) || value < 0 || value > 255) throw new Error("RGB values are 0-255");    }    return new Color(red, green, blue);  }  toString() {    return "rgb(" + this.red + ", " + this.green + ", " + this.blue + ")";  }}
Resultvalid
CallColor.fromHex("#ff8800")
Outputrgb(255, 136, 0)
KindColor instance
Try it yourself

Color.fromHex("#ff8800") returned a Color instance. Its normal instance method toString() produced rgb(255, 136, 0).

A real Color class with two named static factories. Try #336699, steelblue, 256, and negative RGB numbers to see validation paths.

Try invalid values: steelblue, #12, or RGB values outside 0–255. The factory rejects them before an invalid Color object is created. The ordinary instance method toString() still belongs on each color object because it reads that object’s red, green, and blue fields.

Where you’ll use this

Static members are common whenever the class itself has a job, not just each instance. Professional code uses them for utilities, caches, registries, parsers, and creation helpers.

Common uses for static members
UseExampleWhy static fits
Utility namespaceMath.max(1, 5)There is no meaningful Math instance.
Parser or converterDate.parse(text), Array.from(items)The method creates or computes a value from input.
RegistryFormatter.register(name, fn)Every instance should consult the same class-level list.
CacheIcon.load(name) reuses stored iconsA shared lookup prevents duplicated work.
FactoryColor.fromHex("#336699")The method name documents the input format.

Use instance members for behavior that depends on one object’s fields. Use static members when the question starts with “the whole class,” “before an instance exists,” or “which entrance should construct this?”

Common misconceptions

“Static means the value can’t change.”

Static means class-level. Ticket.sold changed from 0 to 2. Use a constant naming convention or a private static field when you want to restrict writes.

“Instances can call static methods.”

Not by default. Ticket.summary() works; ada.summary is undefined because the method is stored on the class, not the instance.

“Static blocks run when I create objects.”

Constructors run for each new. Static blocks run once when the class is defined. They are setup code, not per-instance code.

“Inherited static methods always create base instances.”

If the method uses new this(), a subclass call creates the subclass. this inside a static method is the class used for the call.

“Factory methods are just style.”

They are style plus safety. A factory name documents the input format, centralizes validation, and can return cached or specialized objects without changing callers.

Practice: static members

5 EXERCISES

Try these in order. Predict first, then check against real JavaScript.

Exercise 1 · Warm-upAdd a static counter

Read the code and predict the printed count. Then adapt the pattern in your own editor with a class name you choose.

Starter codePop out in the code editor (opens in a new tab)JavaScript
class Session {
  static count = 0;
  constructor() {
    Session.count += 1;
  }
}
new Session();
new Session();
new Session();
console.log(Session.count);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticePredict static inheritance

    Without running the code, type the three printed values in order.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    class Model {
      static create(name) {
        console.log(this.name);
        return new this(name);
      }
      constructor(name) {
        this.name = name;
      }
    }
    class Admin extends Model {}
    console.log(Object.getPrototypeOf(Admin) === Model);
    const admin = Admin.create("Ada");
    console.log(admin instanceof Admin);

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeWrite a fromJSON factory

      Use the starter as a model: a static factory parses JSON text and returns a normal instance with instance methods.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      class User {
        constructor(name, role) {
          this.name = name;
          this.role = role;
        }
        static fromJSON(text) {
          const data = JSON.parse(text);
          return new User(data.name, data.role ?? "member");
        }
        label() {
          return this.name + " (" + this.role + ")";
        }
      }
      const user = User.fromJSON('{"name":"Ada","role":"admin"}');
      console.log(user.label());

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · ChallengeMove setup into a static block

        This exercise moves one-time setup into static { ... }. Predict the final count.

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        class Settings {
          static loaded = 0;
          static cache;
          static {
            Settings.loaded += 1;
            Settings.cache = { mode: "safe" };
            console.log("read config once");
          }
        }
        new Settings();
        new Settings();
        console.log(Settings.loaded);

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeFix a static method called on an instance

          A teammate wrote user.create("Ada") and got a TypeError. What expression should they call instead?

          Answer, then press Check. Spacing and letter case don’t matter.

            Quiz: check your understanding

            7 QUESTIONS

            Every answer explains itself. Read the explanations even when you get the first try right.

            Lesson quiz · 7 questionsScore: first tries count
            1. Question 1 of 7Where is a static field stored?

              Choose an answer to see the explanation.

            2. Question 2 of 7What does snippet 1 print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              class Counter {
                static value = 0;
                constructor() {
                  Counter.value += 1;
                }
              }
              new Counter();
              new Counter();
              console.log(Counter.value);

              Choose an answer to see the explanation.

            3. Question 3 of 7When does a static block run?

              Choose an answer to see the explanation.

            4. Question 4 of 7What does snippet 2 print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              class Base {
                static create() {
                  console.log(this.name);
                }
              }
              class Child extends Base {}
              Child.create();

              Choose an answer to see the explanation.

            5. Question 5 of 7Which line proves subclasses inherit statics through the class side?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              class Base {}
              class Sub extends Base {}
              console.log(Object.getPrototypeOf(Sub) === Base);

              Choose an answer to see the explanation.

            6. Question 6 of 7Why use Temperature.fromFahrenheit(98.6) instead of overloading new Temperature(98.6)?

              Choose an answer to see the explanation.

            7. Question 7 of 7What does snippet 3 print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              class Tool {
                static create() {
                  return new Tool();
                }
              }
              const tool = new Tool();
              console.log(tool.create);

              Choose an answer to see the explanation.

            Key takeaways

            • Static fields and methods belong to the class constructor function.
            • Instances do not automatically receive static members.
            • Static blocks run once, in order with static fields, while the class is defined.
            • Subclasses inherit public statics; inside a static method, this is the class used for the call.
            • Factory methods are named entrances that validate and explain different ways to create instances.

            Remember the one-liner.
            A static member is a property of the class itself: use it for class-wide data, setup, and named ways to create objects.

            Up next: Private fields & methods, including private instance fields and private statics with # names.

            CompleteFrontend Clear concepts. Working examples.