The static keyword in classes
static makes a property or method part of the class itself, not part of its instances. It is the right tool for shared functions, constants and factory methods that do not depend on any particular object.
Theory
TL;DR
- Regular fields and methods belong to instances; static ones belong to the class.
- Access statics as
ClassName.member. They are not reachable through an instance (u.roleisundefined). - Inside a
staticmethodthisis the class itself, so statics can read and mutate other statics. - Static members are inherited through
extends. - Built in examples:
Math.random(),Date.now(),Object.keys(),Array.isArray(). - ES2022 allows private statics:
static #field.
Quick example
class User {
static role = 'User';
static createGuest() {
return new User('Guest');
}
constructor(name) {
this.name = name;
}
}
console.log(User.role); // 'User'
console.log(User.createGuest()); // User { name: 'Guest' }
const u = new User('Maria');
console.log(u.role); // undefined, an instance does not see staticsWhat a static property or method is
Normally a class's methods and properties belong to instances, that is, to objects created with new:
class User {
constructor(name) {
this.name = name; // belongs to the instance
}
sayHi() { // also belongs to the instance
console.log(`Hi, ${this.name}`);
}
}
const u = new User('Maria');
u.sayHi(); // Hi, MariaAs soon as you add static, the member moves onto the class itself. Statics are reachable only through the class (User), never through its objects (u).
Why it is useful and built in examples
Static properties and methods are used when data or functions:
- do not depend on a particular instance,
- are shared by the whole class.
Examples:
- factory methods (
User.createGuest()), - global constants (
Math.PI), - utility helpers (
Date.now()).
JavaScript itself leans on static in its standard classes:
| Class | Static method |
|---|---|
Math | Math.random(), Math.max() |
Date | Date.now() |
Object | Object.keys(), Object.assign() |
Array | Array.isArray() |
For instance, you never create an instance of
Math, you just callMath.max(1, 5, 9). That is a static method.
Static inheritance and this inside static
If a class extends another one, static members are inherited too:
class Animal {
static category = 'Animals';
static info() {
console.log('This is an animal');
}
}
class Dog extends Animal {}
console.log(Dog.category); // 'Animals'
Dog.info(); // 'This is an animal'So Dog inherited the statics from Animal.
Inside a static method you can reach other static properties through this:
class Counter {
static count = 0;
static increment() {
this.count++;
}
static reset() {
this.count = 0;
}
}
Counter.increment();
Counter.increment();
console.log(Counter.count); // 2
Counter.reset();
console.log(Counter.count); // 0Here
thisinsidestaticis the class itself, not an instance.
Private static fields
ES2022 lets you declare private static properties with #:
class Config {
static #secret = '12345';
static getSecret() {
return this.#secret;
}
}
console.log(Config.getSecret()); // '12345'
console.log(Config.#secret); // SyntaxErrorSuch fields are visible only inside the class itself, not even to subclasses.
Comparison with regular properties
| Characteristic | Regular property | Static property |
|---|---|---|
| Where it lives | On every instance (this) | On the class (ClassName) |
| Reachable through an instance | Yes | No |
| Reachable through the class | No | Yes |
Inherited with extends | Yes | Yes |
this inside the method | The instance | The class |
A real world example, the factory pattern:
class User {
constructor(name, role) {
this.name = name;
this.role = role;
}
static createAdmin(name) {
return new User(name, 'admin');
}
static createGuest() {
return new User('Guest', 'guest');
}
}
const admin = User.createAdmin('Maria');
const guest = User.createGuest();
console.log(admin); // { name: 'Maria', role: 'admin' }
console.log(guest); // { name: 'Guest', role: 'guest' }Handy when objects must be built from a few fixed templates.
Summary table:
What static does | Explanation |
|---|---|
| Attaches a property or method to the class, not to objects | Accessed as ClassName, not through an instance's this |
| Commonly used for utilities, constants, factories | For example, Math.random() |
Inherited with extends | Subclasses get the parent's statics |
Inside static, this points at the class | You can reach other static properties |
Can be made private (static #field) | Visible only inside the class |
Common mistakes
- Reaching for a static through an instance.
u.roleisundefined, because statics live on the class, not on the instance prototype chain. - Confusing
thisin static and instance methods. In a static methodthisis the class; in an instance method it is the instance. - Passing a static method as a callback.
setTimeout(Counter.increment, 0)losesthis; useCounter.increment.bind(Counter)or an arrow wrapper. - Storing per instance state in a static. A static field is one per class, so it effectively becomes a global variable with all the usual problems.
- Assuming private statics are available to subclasses.
static #fieldis visible only inside the class that declares it.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.