Пошук уроків, статей та іншого контенту
Керуйте доступом до членів класу й забороняйте зміну властивостей за допомогою public, private, protected і readonly.
Модифікатори доступу визначають, де можна використовувати властивості та методи класу:
public — доступні всюди;
private — доступні лише всередині того самого класу;
protected — доступні всередині класу та його нащадків;
readonly — значення можна призначити лише під час оголошення або в конструкторі.
Модифікатори допомагають приховати внутрішню реалізацію класу та захистити його стан від неправильних змін.
publicpublic означає, що член класу доступний з будь-якого коду.
Він є модифікатором за замовчуванням, тому його можна не записувати явно:
class User {
public name: string;
constructor(name: string) {
this.name = name;
}
public greet(): string {
return `Привіт, ${this.name}!`;
}
}
const user = new User("Олена");
console.log(user.name);
console.log(user.greet());
user.name = "Андрій";
console.log(user.greet());У цьому прикладі властивість name і метод greet доступні за межами класу.
Такий запис еквівалентний:
class User {
name: string;
greet(): string {
return `Привіт, ${this.name}!`;
}
}privateprivate обмежує доступ до члена класу. Його можна використовувати лише в самому класі.
class BankAccount {
private balance: number;
constructor(initialBalance: number) {
this.balance = initialBalance;
}
public deposit(amount: number): void {
if (amount > 0) {
this.balance += amount;
}
}
public getBalance(): number {
return this.balance;
}
}
const account = new BankAccount(100);
account.deposit(50);
console.log(account.getBalance()); // 150Безпосередній доступ до balance заборонений:
// Помилка TypeScript:
// account.balance = 100000;Замість прямої зміни приватної властивості клас надає публічні методи deposit і getBalance. Так клас контролює, як змінюється його внутрішній стан.
privateперевіряється TypeScript під час компіляції. Код, який звертається до приватного члена ззовні, не пройде перевірку типів.
protectedprotected дозволяє доступ до члена:
у самому класі;
у класах, які його наслідують.
З коду за межами класу та його нащадків доступу немає.
class Employee {
protected department: string;
constructor(department: string) {
this.department = department;
}
}
class Developer extends Employee {
public describe(): string {
return `Розробник працює у відділі: ${this.department}`;
}
}
const developer = new Developer("Frontend");
console.log(developer.describe());
// Помилка TypeScript:
// console.log(developer.department);Метод describe має доступ до department, тому що Developer успадковує Employee.
Водночас зовнішній код не може звернутися до department напряму.
readonlyreadonly забороняє повторне присвоєння властивості після її ініціалізації.
Властивість можна ініціалізувати:
одразу під час оголошення;
у конструкторі.
class Product {
readonly id: number;
public name: string;
constructor(id: number, name: string) {
this.id = id;
this.name = name;
}
rename(newName: string): void {
this.name = newName;
}
}
const product = new Product(101, "Ноутбук");
console.log(product.id);
product.rename("Ігровий ноутбук");
console.log(product.name);
// Помилка TypeScript:
// product.id = 202;Метод rename може змінити name, але не id. Це гарантує, що ідентифікатор товару не зміниться після створення об’єкта.
Властивість, оголошену як readonly, не обов’язково робити private. Наприклад, id доступний для читання ззовні, але недоступний для зміни.
Модифікатори можна поєднувати. Наприклад, властивість може бути одночасно private і readonly:
class Session {
private readonly token: string;
constructor(token: string) {
this.token = token;
}
public getToken(): string {
return this.token;
}
}
const session = new Session("abc-123");
console.log(session.getToken());
// Помилки TypeScript:
// session.token = "new-token";
// console.log(session.token);У цьому прикладі:
private приховує token від зовнішнього коду;
readonly не дозволяє змінити token після створення об’єкта;
метод getToken надає контрольований доступ для читання.
| Модифікатор | У класі | У нащадку | Ззовні | |---|---:|---:|---:| | public | так | так | так | | protected | так | так | ні | | private | так | ні | ні | | readonly | читання і початкове присвоєння | залежить від доступу | лише читання після ініціалізації |
readonly не визначає, хто може читати властивість. Він визначає, чи можна повторно змінити її значення.
Наприклад:
class Order {
public readonly number: string;
constructor(number: string) {
this.number = number;
}
}Тут number можна читати ззовні, але не можна змінити.
readonlyclass User {
readonly id: number;
constructor(id: number) {
this.id = id;
}
}
const user = new User(1);
// Помилка TypeScript:
// user.id = 2;Після ініціалізації id не можна присвоїти нове значення.
private ззовніclass Password {
private value: string;
constructor(value: string) {
this.value = value;
}
}
const password = new Password("secret");
// Помилка TypeScript:
// console.log(password.value);Для доступу до приватних даних потрібно створити публічний метод, якщо такий доступ справді необхідний.
protected ззовніclass Animal {
protected name: string = "Тварина";
}
class Dog extends Animal {
getName(): string {
return this.name;
}
}
const dog = new Dog();
console.log(dog.getName());
// Помилка TypeScript:
// console.log(dog.name);protected призначений для самого класу та його нащадків, а не для зовнішнього коду.
readonly робить весь об’єкт незміннимreadonly захищає конкретну властивість від повторного присвоєння. Він не робить автоматично незмінними всі вкладені дані об’єкта.
class Settings {
readonly options: { theme: string };
constructor(theme: string) {
this.options = { theme };
}
}
const settings = new Settings("light");
// Саме посилання не можна замінити:
// settings.options = { theme: "dark" };
// Але властивість вкладеного об’єкта можна змінити:
settings.options.theme = "dark";
console.log(settings.options.theme);Якщо потрібно заборонити зміну і вкладених властивостей, їх також потрібно описати як readonly.
Використовуйте public, коли член справді є частиною зовнішнього інтерфейсу класу.
Використовуйте private, щоб приховати внутрішню реалізацію.
Використовуйте protected, коли нащадкам потрібен доступ до внутрішньої частини базового класу.
Використовуйте readonly для ідентифікаторів, дат створення та інших значень, які не повинні змінюватися після створення об’єкта.
Не робіть усі властивості public без потреби: це ускладнює контроль за станом об’єкта.
public дозволяє доступ до члена звідусіль і використовується за замовчуванням.
private дозволяє доступ лише всередині поточного класу.
protected дозволяє доступ у класі та його нащадках.
readonly забороняє повторне присвоєння властивості після її ініціалізації.
Модифікатори можна комбінувати, наприклад private readonly.
Контроль доступу допомагає приховувати внутрішню реалізацію та захищати дані класу.