Ключове слово static у класах
static робить властивість або метод частиною класу, а не частиною його екземплярів. Це ідеальний інструмент для спільних функцій, констант і фабричних методів, які не залежать від конкретного об'єкта.
Теорія
TL;DR
- Звичайні поля й методи належать екземплярам, статичні, самому класу.
- Доступ до статики:
ClassName.member. Через екземпляр вона недоступна (u.roleдастьundefined). - Усередині
staticметодаthis, це сам клас, тож статика може читати й змінювати іншу статику. - Статичні члени успадковуються при
extends. - Вбудовані приклади:
Math.random(),Date.now(),Object.keys(),Array.isArray(). - ES2022 дозволяє приватну статику:
static #field.
Швидкий приклад
class User {
static role = 'Користувач';
static createGuest() {
return new User('Гість');
}
constructor(name) {
this.name = name;
}
}
console.log(User.role); // 'Користувач'
console.log(User.createGuest()); // User { name: 'Гість' }
const u = new User('Maria');
console.log(u.role); // undefined, екземпляр не бачить статикуЩо таке статична властивість або метод
Зазвичай методи й властивості класу належать екземплярам, тобто об'єктам, створеним через new:
class User {
constructor(name) {
this.name = name; // належить екземпляру
}
sayHi() { // теж належить екземпляру
console.log(`Привіт, ${this.name}`);
}
}
const u = new User('Maria');
u.sayHi(); // Привіт, MariaЩойно додаємо static, член переїжджає на сам клас. Статика доступна тільки через клас (User), а не через його об'єкти (u).
Навіщо це потрібно і вбудовані приклади
Статичні властивості й методи використовують, коли дані або функції:
- не залежать від конкретного екземпляра,
- спільні для всього класу.
Приклади:
- фабричні методи (
User.createGuest()), - глобальні константи (
Math.PI), - службові утиліти (
Date.now()).
Сам JavaScript активно використовує static у стандартних класах:
| Клас | Статичний метод |
|---|---|
Math | Math.random(), Math.max() |
Date | Date.now() |
Object | Object.keys(), Object.assign() |
Array | Array.isArray() |
Наприклад, ви не створюєте екземпляр
Math, а просто викликаєтеMath.max(1, 5, 9). Це і є статичний метод.
Успадкування статики та this всередині static
Якщо клас наслідує інший через extends, то статичні члени теж успадковуються:
class Animal {
static category = 'Тварини';
static info() {
console.log('Це тварина');
}
}
class Dog extends Animal {}
console.log(Dog.category); // 'Тварини'
Dog.info(); // 'Це тварина'Тобто Dog успадкував статику від Animal.
Усередині статичного методу можна звертатися до інших статичних властивостей через 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); // 0Тут
thisусерединіstatic, це сам клас, а не екземпляр.
Приватні статичні поля
ES2022 дозволяє оголошувати приватні статичні властивості через #:
class Config {
static #secret = '12345';
static getSecret() {
return this.#secret;
}
}
console.log(Config.getSecret()); // '12345'
console.log(Config.#secret); // SyntaxErrorТакі поля видно тільки всередині самого класу, навіть нащадки їх не бачать.
Порівняння зі звичайними властивостями
| Характеристика | Звичайна властивість | Статична властивість |
|---|---|---|
| Де зберігається | У кожному екземплярі (this) | У самому класі (ClassName) |
| Доступ через екземпляр | Так | Ні |
| Доступ через клас | Ні | Так |
Успадковується при extends | Так | Так |
Контекст this у методі | Екземпляр | Клас |
Реальний приклад, фабричний метод (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');
}
}
const admin = User.createAdmin('Maria');
const guest = User.createGuest();
console.log(admin); // { name: 'Maria', role: 'admin' }
console.log(guest); // { name: 'Гість', role: 'guest' }Зручно, коли треба створювати об'єкти за певними шаблонами.
Підсумкова таблиця:
Що робить static | Пояснення |
|---|---|
| Прив'язує властивість або метод до класу, а не до об'єктів | Доступ через ClassName, не через this екземпляра |
| Часто використовується для утиліт, констант, фабрик | Наприклад, Math.random() |
Успадковується при extends | Нащадки отримують статику батька |
Усередині static this вказує на сам клас | Можна звертатися до інших статичних властивостей |
Можна зробити приватним (static #field) | Видно тільки всередині класу |
Типові помилки
- Звертатися до статики через екземпляр.
u.roleдастьundefined, бо статика живе на класі, а не в ланцюжку прототипів екземпляра. - Плутати
thisу статичному й звичайному методі. У статичномуthis, це клас, у звичайному, екземпляр. - Передавати статичний метод як колбек.
setTimeout(Counter.increment, 0)втратитьthis, требаCounter.increment.bind(Counter)або стрілкову обгортку. - Тримати в статиці стан, який має бути в екземплярі. Статичне поле одне на весь клас, тому воно перетворюється на глобальну змінну з усіма її проблемами.
- Вважати, що приватна статика доступна нащадкам.
static #fieldвидно лише всередині класу, де його оголошено.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.