Класи в JS
Що таке клас
Клас - це синтаксичний цукор над функцією-конструктором і прототипами.
Тобто "під капотом" класи працюють так само, як і раніше в JavaScript, але виглядають і читаються значно простіше.
Приклад простого класу
class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHi() {
console.log(`Привіт, мене звати ${this.name}`);
}
}
const user1 = new User('Alex', 25);
user1.sayHi(); // Привіт, мене звати Alexclass - оголошує клас
constructor() - спеціальний метод, який викликається при new User()
this - посилання на об'єкт, що створюється
Методи в класі автоматично потрапляють у prototype
Як це виглядає під капотом
Цей код:
class User {
constructor(name) {
this.name = name;
}
sayHi() {
console.log(this.name);
}
}еквівалентний старому ES5-коду:
function User(name) {
this.name = name;
}
User.prototype.sayHi = function() {
console.log(this.name);
};Ключові особливості класів
| Можливість | Опис |
|---|---|
| constructor() | Метод, який виконується при створенні об'єкта (new) |
| методи класу | Додаються в prototype і доступні всім екземплярам |
| extends | Наслідування від іншого класу |
| super() | Виклик конструктора батька |
| static | Статичні методи/властивості, належать самому класу |
приватні поля (#) | Поля, недоступні поза класом |
| геттери/сеттери | Дозволяють керувати читанням і записом властивостей |
Приклад з наслідуванням
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} видає звук.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // викликає constructor батька
this.breed = breed;
}
speak() {
console.log(`${this.name} гавкає!`);
}
}
const rex = new Dog('Rex', 'shepherd');
rex.speak(); // Rex гавкає!extends - зв'язує прототипи класів
super() - викликає constructor батька
Можна перевизначати методи (як у класичному ООП)
Статичні методи і властивості
class MathUtil {
static add(a, b) {
return a + b;
}
}
console.log(MathUtil.add(2, 3)); // 5static - метод належить самому класу, а не його екземплярам.
Приватні поля і методи (#)
Додані в ES2022:
class Account {
#balance = 0; // приватне поле
deposit(amount) {
this.#balance += amount;
}
getBalance() {
return this.#balance;
}
}
const acc = new Account();
acc.deposit(100);
console.log(acc.getBalance()); // 100
console.log(acc.#balance); // Помилка: приватна властивістьПоля з # доступні тільки всередині класу.
Геттери і сеттери
class User {
constructor(name) {
this._name = name;
}
get name() {
return this._name.toUpperCase();
}
set name(value) {
this._name = value.trim();
}
}
const user = new User(' tim ');
console.log(user.name); // TIM
user.name = ' Alex ';
console.log(user.name); // ALEXДозволяють керувати тим, як властивості читаються і змінюються.
Класові вирази
Клас можна оголосити як вираз:
const User = class {
sayHi() {
console.log('Hi!');
}
};
new User().sayHi(); // Hi!Або навіть дати йому ім'я тільки всередині визначення:
const User = class MyUser {
getClassName() {
return MyUser.name;
}
};Відмінність класів від функцій-конструкторів
| Критерій | Функція-конструктор | Клас |
|---|---|---|
| Синтаксис | Старий, громіздкий | Сучасний, декларативний |
new обов'язковий | Так | Так |
| Методи | Через prototype | Усередині тіла класу |
Поведінка this | Може бути непередбачуваною | Зрозуміла, стандартна |
Підтримка extends | Ручна | Вбудована |
| Приватні поля | Немає | Є (через #) |
Важливо пам'ятати
- Класи не піднімаються (не hoistяться), як функції.
const user = new User(); // ReferenceError
class User {}- Усередині класу всі методи не перелічувані (non-enumerable), на відміну від звичайних властивостей у прототипах.
- Класи - синтаксичний цукор над прототипами, а не нова модель наслідування.
Коротке резюме
| Поняття | Що робить |
|---|---|
class | Оголошує клас |
constructor | Метод, що викликається при new |
extends | Наслідування |
super() | Виклик батьківського конструктора |
static | Методи класу, а не екземпляра |
#field | Приватна властивість |
get / set | Керування доступом до властивостей |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.