Static Members
static declares a method or property that belongs to the class itself, not to its instances. You call it through the class — MyClass.help() — and it has no access to a specific instance's data. Static members shine as factories, validators, constants, and bundle-of-utilities homes that still feel related to a class.
Static methods
class Temperature {
constructor(celsius) { this.celsius = celsius; }
// Instance method
toFahrenheit() { return this.celsius * 9 / 5 + 32; }
// Static method — utility, no instance needed
static fromFahrenheit(f) {
return new Temperature((f - 32) * 5 / 9);
}
}
const t = Temperature.fromFahrenheit(212);
console.log(t.toFahrenheit()); // 212A common pattern: pair the constructor with one or more static factories named after the input format (fromJSON, fromFahrenheit, ofSeconds).
Static properties
A static field declaration attaches a property to the class. Use it for shared constants, default values, or registries.
class HttpClient {
static DEFAULT_TIMEOUT = 5000;
static USER_AGENT = "letcodes/1.0";
constructor({ timeout = HttpClient.DEFAULT_TIMEOUT } = {}) {
this.timeout = timeout;
}
}
console.log(HttpClient.DEFAULT_TIMEOUT); // 5000
console.log(new HttpClient().timeout); // 5000Calling static from instance code
Inside an instance method, the class is accessible via this.constructor (the class that built this object). That works even after subclassing.
class Shape {
static describe() { return "a shape"; }
describe() {
// Refer to the actual class via this.constructor
return `I am ${this.constructor.describe()}`;
}
}
class Circle extends Shape {
static describe() { return "a circle"; }
}
console.log(new Shape().describe()); // 'I am a shape'
console.log(new Circle().describe()); // 'I am a circle' — uses Circle's staticthis inside a static method
Inside a static method, this is the class itself. That sounds odd, but it is what makes inherited static methods work correctly with subclasses.
class Model {
static create(data) {
return new this(data); // `this` is the actual class — subclass-friendly
}
}
class User extends Model {
constructor({ name }) { super(); this.name = name; }
}
const u = User.create({ name: "Ada" });
console.log(u instanceof User); // true — not just ModelStatic initialiser blocks
Modern JavaScript lets you put a static { ... } block in a class. It runs once when the class is evaluated and can populate static state with arbitrary logic.
class Registry {
static items = new Map();
static {
Registry.items.set("default", { id: 0 });
Registry.items.set("admin", { id: 1 });
}
static get(name) { return Registry.items.get(name); }
}
console.log(Registry.get("admin")); // { id: 1 }Static inheritance
When a class extends another, its statics inherit too. Subclass.help walks the prototype chain of the class object itself, just as instances walk theirs.
class Animal {
static kingdom = "Animalia";
static info() { return "A living organism"; }
}
class Cat extends Animal {}
console.log(Cat.kingdom); // 'Animalia'
console.log(Cat.info()); // 'A living organism'
// Inheriting class can override
class Plant extends Animal {
static kingdom = "Plantae";
}
console.log(Plant.kingdom); // 'Plantae'When to use static — and when not
Use static for factories that produce instances from various input formats.
Use static for type guards:
Animal.isAnimal(x).Use static for constants related to the class — values that never change per instance.
Do not use static to dodge
this. If your method ignores instance data, it might belong as a plain top-level function instead.Do not use static to store mutable global state by accident — every test sees the same data.
Static methods inside a base class
class Validator {
static isEmail(s) {
return typeof s === "string" && /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(s);
}
static isPhone(s) {
return typeof s === "string" && /^[0-9 +()-]{6,}$/.test(s);
}
}
console.log(Validator.isEmail("ada@example.com")); // true
console.log(Validator.isPhone("abc")); // falseThis pattern — a class as a namespace for related helpers — is so common that it sometimes replaces a module of free functions in larger codebases.