Static Initialization Blocks in JavaScript Classes

Static initialization blocks in JavaScript provide a dedicated mechanism to execute complex configuration logic for static properties directly within a class declaration. This article explains what static initialization blocks are, how their syntax works, and precisely when the JavaScript engine executes them during runtime.

What is a Static Initialization Block?

A static initialization block is a block of code marked with the static keyword inside a class body. It allows you to run statements, execute logic, and set up static properties when a class is loaded, rather than waiting for an instance to be constructed.

Prior to static blocks, initializing static properties with logic like loops, conditional branching, or try...catch blocks required writing code outside the class declaration. Static blocks keep all static configuration encapsulated inside the class definition itself.

class DatabaseConnection {
  static defaultPort;
  static connectionString;

  static {
    try {
      const envPort = process.env.DB_PORT;
      this.defaultPort = envPort ? parseInt(envPort, 10) : 5432;
      this.connectionString = `localhost:${this.defaultPort}`;
    } catch (error) {
      this.defaultPort = 5432;
      this.connectionString = 'localhost:5432';
    }
  }
}

When Do Static Initialization Blocks Execute?

Static initialization blocks execute immediately when the class is evaluated by the JavaScript engine—meaning at class definition time.

Key execution rules include:

  1. Before Instantiation: They run before any instance of the class is created using new and before any static methods or properties are accessed externally.
  2. Order of Declaration: If a class contains multiple static fields and static blocks, they execute sequentially in the exact order they appear in the source code.
  3. Inheritance Order: In class hierarchies with extends, the superclass static blocks execute before the subclass static blocks.
  4. Single Execution: They execute only once per class definition evaluation, not per instance creation.
class Example {
  static first = (() => { console.log('1. Static field initialized'); return 1; })();

  static {
    console.log('2. First static block executed');
  }

  static second = (() => { console.log('3. Second static field initialized'); return 2; })();

  static {
    console.log('4. Second static block executed');
  }
}
// Output upon script load:
// 1. Static field initialized
// 2. First static block executed
// 3. Second static field initialized
// 4. Second static block executed

Privileged Access to Private Fields

A unique capability of static initialization blocks is their privileged access to private properties (#field) and private methods. A static block can access private instance fields and export access functions, enabling controlled private state sharing across different scopes without exposing the fields globally.

let getPrivateField;

class SecureContainer {
  #secret;

  constructor(secret) {
    this.#secret = secret;
  }

  static {
    // Expose access to the private field via a closure
    getPrivateField = (instance) => instance.#secret;
  }
}

const item = new SecureContainer('confidential-data');
console.log(getPrivateField(item)); // "confidential-data"

Summary

Static initialization blocks (static { ... }) streamline class-level setup by providing a clean, scoped environment for complex static variable initialization and private field bridging. They run synchronously and exactly once at the moment the class declaration is evaluated.