completefrontend
Open lab My progress
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 shared counts, shared lists, and tools that need no object.
  • 02
    Know when class setup runsSay when static fields and static blocks run, and show that they run only once.
  • 03
    Write clear factory methodsWrite static methods such as fromJSON and fromHex that make objects, each named for its kind of input.

Members that belong to the class

A class is a plan for making objects. Each object made from the class is called an instance. For example, one user, one ticket, or one color.

A member is a field (a stored value) or a method (a function) that a class defines. Most members belong to each instance. A static member is different: it belongs to the class itself. You use it with the class name, like ClassName.member. You don't use it with an instance, like instance.member.

Why can a class hold things? In JavaScript, a class is a special kind of function, and a function is an object. So a class can have its own properties, like any object. A static field is one of those properties. A static method is a function stored as one of those properties.

Real-life analogyThe factory and its cars

Think of a car factory. The factory keeps a count of how many cars it has built. It also keeps the steps for building a car from a serial number. Each car keeps its own mileage and has its own horn. You would not write the factory's total inside every car. You would not write one car's mileage on the factory wall. Static members are what the factory keeps for itself.

In real life: The factory's count of cars built
In JavaScript: Car.built, a static field
In real life: The factory's steps for building a car from a serial number
In JavaScript: Car.fromSerial(...), a static method
In real life: One car's mileage
In JavaScript: car.mileage, an instance field
In real life: One car's horn button
In JavaScript: car.honk(), an instance method

The table compares the two kinds of member. Read each row as a question, then the answer for each kind.

Static members and instance members side by side
QuestionStatic memberInstance member
How do you call it?With the class name: User.create(raw).With one object: user.save().
Where does JavaScript find it?On the class itself.On the object, or on the shared methods of its class.
What is this inside a method?Usually the class, such as User.One object, such as user.
What is it good for?Counts, lists, setup, and ways to make objects.Work that reads or changes one object's data.

In this lesson you will:

  • count objects with one shared field,
  • watch class setup code run before any object exists,
  • see that a subclass gets the static members of its parent class,
  • write methods that make objects, like Temperature.fromFahrenheit(98.6).

Static fields and methods

STEP THROUGH

To make a static member, write the word static in front of a field or method inside the class. JavaScript then puts that member on the class. It does not copy the member onto the objects you make later.

One counter for every cartPop out in the code editor (opens in a new tab)JavaScript
class Cart {  static itemCount = 0;  constructor(item) {    this.item = item;    Cart.itemCount += 1;  }}const tea = new Cart("tea");const book = new Cart("book");console.log(Cart.itemCount);console.log(tea.item);

Line 2 makes one itemCount field on the class Cart. It starts at 0. Line 5 runs every time you write new Cart(...). It adds 1 to that same field. Lines 8 and 9 make two carts, so the count becomes 2.

Line 10 prints Cart.itemCount, which is 2. Line 11 prints tea.item, which is tea. Each cart has its own item, but there is only one itemCount.

The Cart class holds one card, itemCount: 2. Below it are two objects. The tea cart holds item: tea and the book cart holds item: book. An arrow marked +1 goes from each object up to the class.the class itselfitemCount: 2Cart+1+1item: "tea"teaitem: "book"book
The class Cart holds the only itemCount. Each new Cart() adds 1 to it, so it ends at 2, while each object keeps just its own item.

The next example adds a static method too. Press Step to walk through it one line at a time.

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

Step through two new tickets. Watch one static field count both of them. Then see that neither ticket has the static method.

Running in
  1. script
Next: line 2
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);
CallStoreChangeResultBlue line: runs next. 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.

This is the usual shape. A static field stores a value that all objects share. The constructor or a method changes it. The last line shows something important: ada.summary is undefined. The method summary starts with static, so it lives on Ticket, not on ada.

Static does not mean the value is fixed

A static field can change. Ticket.sold starts at 0, then becomes 1, then 2. The word static means "on the class". It does not mean "cannot change". To protect a value, use a private field (next lesson) or a naming rule your team agrees on.

An object can't call a static methodPop out in the code editor (opens in a new tab)JavaScript
class Ticket {  static summary() {    return "ready";  }}const ticket = new Ticket();console.log(ticket.summary());

Line 7 fails with a TypeError. The object ticket has no summary, so ticket.summary is undefined, and you can't call undefined. The fix is to call it on the class: Ticket.summary().

A static method is also handy when you don't need an object at all. JavaScript's own built-in tools work this way:

Built-in static methodsPop 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 finds the biggest number. You never write new Math(); you just use the tool.
  • Date.parse turns date text into a number: the milliseconds since 1970.
  • Array.from makes a new array from something else, here the letters of "JS".
  • Object.fromEntries makes a new object from a list of pairs.

The last two make new values from a different kind of input. Remember that idea; it comes back in factory methods at the end of the lesson.

Static or instance?
  • User.fromJSON(raw) reads data and returns a new user
  • user.fullName() reads this.firstName and this.lastName
  • Ticket.sold counts every ticket made so far
  • car.mileage is different for every car
  • Plugin.registry keeps a list of all plugins by name
  • article.render() shows this article's title and body
Try it yourself
0 of 6 correct

Put each member on the class or on one object. Ask: does it need one object's data, or does it belong to the whole class?

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

Static blocks: setup that runs once

INTERACTIVE

A static field can hold a simple starting value. Sometimes the setup needs several lines of code, like filling a list. For that, use a static block: the word static followed by curly braces, static { ... }, inside the class.

A static block runs exactly once, while JavaScript is making the class. It finishes before the code after the class runs.

Fill a list oncePop out in the code editor (opens in a new tab)JavaScript
class Parser {  static formats = [];  static {    Parser.formats.push("json", "text");  }}console.log(Parser.formats.join(", "));

Line 2 makes an empty list, Parser.formats. Lines 3 to 5 are the static block. It adds "json" and "text" to the list. Line 7 prints json, text. If you made a Parser object later, the block would not run again.

Real-life analogyGetting the factory ready on opening day

Before a factory builds its first car, someone opens the doors, sets up the machines, and writes the first notes. This happens once, not once per car. A static block is that opening-day setup for a class.

In real life: Turn on and set up the machines
In JavaScript: Run the static { ... } block
In real life: Write the first notes on the factory board
In JavaScript: Fill the class's static fields
In real life: Build the first car, later
In JavaScript: Call new ClassName(...) later

Now step through a longer example. Watch for two things: the static block prints before after class definition, and before the constructor prints Ada #1.

Class setup runs before any object
Step 0 of 9Ready
Your turn: follow the blue line

Before you press Step, guess which line prints first. Static fields and blocks run while the class is being made, before any constructor call.

Running in
  1. script
Next: line 2
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);
CallStoreChangeResultBlue line: runs next. 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.
A console with four lines in order: static block ran, after class definition, Ada #1, and 1. Beside each line is where it came from: the static block, the line after the class, the constructor, and setupLog.length.Consolestatic block ranafter class definitionAda #111. static block, once2. line after the class3. the constructor4. setupLog.length
The static block prints first, while the class is still being made. Only then does the rest of the program run, including new Workshop("Ada").

Static fields and static blocks run from top to bottom, in the order you wrote them. A block can use the static fields written above it. The clearest code puts the fields first and the block that fills them right after.

A subclass gets the static members too

STEP THROUGH

A subclass is a class made with extends, like class Admin extends Model. The class it extends, Model, is the parent class.

extends makes two links:

  • Each Admin object can use the instance methods of Model.
  • The class Admin itself can use the static members of Model.

You can check the second link with Object.getPrototypeOf(Admin) === Model. It gives true. Object.getPrototypeOf(x) returns the object that x falls back to when it doesn't have a property.

A subclass uses its parent's create methodPop out in the code editor (opens in a new tab)JavaScript
class Model {  static create(name) {    return new this(name);  }  constructor(name) {    this.name = name;  }}class Admin extends Model {}const admin = Admin.create("Asha");console.log(admin.constructor === Admin);

Line 9 makes Admin with no members of its own. Line 10 calls Admin.create("Asha"). Admin has no create, so JavaScript follows the link and finds it on Model.

Inside a static method, this is the class you called it on. Here that is Admin. So on line 3, new this(name) means new Admin(name). Line 11 prints true.

Admin.create("Asha"). The Admin cart is empty and links to the Model cart, which holds create(). The method is found on Model, but this is Admin, so new this() makes an Admin.Admin.create("Asha")Adminextendscreate()Modelthis = Adminnew this() makes an Admincreate() is found here
Admin has no create() of its own, so JavaScript finds it on Model. The call still starts from Admin, so this is Admin and the result is an Admin.
A parent's static method, with the subclass as this
Step 0 of 6Ready
Your turn: follow the blue line

Guess the three printed values first. The key question: when a subclass calls its parent's static method, what is this?

Running in
  1. script
Next: line 10
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);
CallStoreChangeResultBlue line: runs next. 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 key is this. When you call User.create("Ada"), the method runs with this set to User, even though it was written in BaseModel. Because the parent's method says new this(name), each subclass gets objects of its own kind.

Private static members come next

This lesson covers public static members, which any code can use. Private static members have names that start with #, and only code inside the class can use them. The next lesson, Private fields & methods, explains them.

Factory methods: named ways to make objects

INTERACTIVE

A class has only one constructor. But you may want to make the same kind of object from different inputs. A factory method is a static method that makes an object and returns it. Its name tells the reader what kind of input it takes.

The method name 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);

The constructor on lines 2 to 4 stores a temperature in Celsius. The factory method on lines 5 to 7 takes Fahrenheit, changes it to Celsius, and then calls new Temperature(...). Line 9 uses it, so normal.celsius is 37.

Temperature.fromFahrenheit(98.6). The card 98.6, in Fahrenheit, goes into the fromFahrenheit() method, which converts it to Celsius. Out comes the normal object, holding celsius: 37.Temperature.fromFahrenheit(98.6)98.6FahrenheitfromFahrenheit()changes to Celsiuscelsius: 37normala Temperature
The method name says the number is in Fahrenheit. The method changes it to Celsius and then calls new Temperature(37).

Compare it with new Temperature(98.6). A reader can't tell if 98.6 is Celsius or Fahrenheit. Temperature.fromFahrenheit(98.6) says it clearly. A factory method can also:

  • check the input and throw an error if it is wrong,
  • tidy the input into the shape the constructor expects,
  • pick which subclass to make,
  • give back an object it made earlier, instead of a new one.
Make a color two ways
Color with two factory methodsPop 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 object
Try it yourself

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

A real Color class with two static factory methods. Pick Hex or RGB, then type a value. Try #336699, steelblue, 256, and a negative number to see each check fail or pass.

Try wrong inputs: steelblue, #12, or a number outside 0 to 255. Each factory method throws an error before any Color object is made. The method toString() is a normal instance method, because it reads one color's own red, green, and blue.

A factory method that reads JSON textPop 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 + ")";  }}console.log(User.fromJSON('{"name":"Asha"}').label());

JSON is a text format for data. On line 7, JSON.parse(text) turns that text into an object. Line 8 makes the user. The text has no role, so data.role is undefined, and ?? "member" uses "member" instead. Line 14 prints Asha (member).

Where you'll use this

Use a static member when the job belongs to the class as a whole, not to one object. Each row of the table is one common job, a real example, and why static fits it.

Common jobs for static members
JobExampleWhy it belongs on the class
A set of toolsMath.max(1, 5)There is no single Math object to make. You just use the tool.
Turn one kind of data into anotherDate.parse(text), Array.from(items)The method makes a new value from the input.
A shared listFormatter.register(name, fn)Every object should use the same list.
Remember earlier resultsIcon.load(name) reuses icons it loaded beforeOne shared store saves doing the same work twice.
Make objectsColor.fromHex("#336699")The method name says what kind of input it takes.

Use an instance member when the work depends on one object's own data. Use a static member when the question is about the whole class, or when no object exists yet.

Common misconceptions

"Static means the value can't change."

Static means "on the class". Ticket.sold changed from 0 to 2. To stop other code changing a value, use a private static field.

"Objects can call static methods."

They can't. Ticket.summary() works, but ada.summary is undefined. The method is on the class, not on the object.

"A static block runs every time I make an object."

The constructor runs for each new. A static block runs once, while the class is being made.

"A parent's static method always makes parent objects."

If the method uses new this(), calling it on a subclass makes a subclass object. Inside a static method, this is the class you called it on.

"Factory methods are only about style."

They also make code safer. The name says what input the method takes. The method can check that input in one place, and it can return a saved object or a subclass without the calling code changing.

Practice: static members

5 EXERCISES

Do these in order. Guess the answer first, then check it.

Exercise 1 · Warm-upAdd a static counter

Read the code and guess the number it prints. Then write the same 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 what a subclass gets

    Don't run 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 method

      Use the code as a model. The static method reads JSON text and returns a normal User object, which has the normal method label().

      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 code puts one-time setup in static { ... }. Guess the number it prints at the end.

        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 object

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

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

            Quiz: check your understanding

            7 QUESTIONS

            Each answer comes with a short reason. Read the reason even when you got it right.

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

              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 7This code checks the link that extends makes between two classes. What does it print?

              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 write Temperature.fromFahrenheit(98.6) instead of 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 live on the class itself.
            • Objects made from the class don't get static members.
            • Static fields and static blocks run once, top to bottom, while the class is being made.
            • A subclass can use its parent's public static members. Inside a static method, this is the class you called it on.
            • Factory methods are static methods with clear names that check their input and make objects.

            Remember the one-liner.
            A static member belongs to the class itself: use it for shared data, one-time setup, and named ways to make objects.

            Up next: Private fields & methods. You'll learn names that start with #, which only code inside the class can use, including private static members.

            CompleteFrontend Clear concepts. Working examples.