A static method, accessor, or field is defined on the constructor function itself. Instances never get it, and it's called as Class.method(). this inside a static method is whatever it was called on, normally the class.
Subclasses inherit statics because class B extends A sets B.[[Prototype]] to A, so B.method is found through the chain and super.method() works inside static methods.
Static fields are initialised during class evaluation with define semantics, after all methods exist, with this bound to the class. A static initialization block (static { ... }) is a body of statements evaluated at the same stage:
- Static fields and blocks run once, in source order, interleaved. A later one sees what an earlier one set.
thisis the class.super.xreads the parent's static.- The block has its own function-like scope:
varandletinside are local to it. - It can read private names (
#x) declared in the class, which is how a class can export access to its private state to a sibling function in the surrounding scope. await,arguments, andreturnare syntax errors.- It is evaluated synchronously during the class definition itself. An error thrown there propagates out of the class definition.
Use blocks when field initialisers can't express the setup: try/catch around parsing, setting several statics from one computation, or wiring private-state access. For a single value, a plain static x = ... is enough.