9.1 Основні концепції
Інкапсуляція — це одна з ключових концепцій об'єктно-орієнтованого програмування (ООП), яка дозволяє приховувати внутрішні деталі реалізації об'єкта та надавати доступ до цих деталей через строго визначені інтерфейси. Це допомагає покращити безпеку та спрощує управління кодом.
Переваги інкапсуляції:
- Приховування даних: інкапсуляція дозволяє приховувати внутрішні деталі реалізації та надавати доступ тільки до необхідних методів і властивостей. Це запобігає некоректному використанню об'єктів та покращує безпеку коду.
- Контроль доступу: інкапсуляція дозволяє контролювати доступ до даних і методів, надаючи можливість змінювати внутрішній стан об'єкта лише через певні методи.
- Підтримуваність: інкапсуляція покращує підтримку коду, оскільки зміни в реалізації не впливають на зовнішній інтерфейс класу. Це дозволяє вносити зміни в реалізацію без зміни коду, що використовує клас.
- Покращення тестування: інкапсуляція дозволяє ізолювати внутрішню реалізацію об'єкта, що спрощує модульне тестування та зменшує ймовірність виникнення побічних ефектів.
У JavaScript інкапсуляція реалізується за допомогою методів і властивостей, а починаючи з ES2022, також стали доступними приватні поля та методи.
9.2 Інкапсуляція через замикання
До введення приватних полів в ES2022, інкапсуляція в JavaScript часто досягалася з використанням замикань.
Приклад:
- Змінна
countдоступна тільки всередині функціїcreateCounterі недоступна ззовні - Методи
increment,decrementіgetCountможуть взаємодіяти з приватною змінноюcount
function createCounter() {
let count = 0; // приватна змінна
return {
increment() {
count++;
console.log(count);
},
decrement() {
count--;
console.log(count);
},
getCount() {
return count;
}
};
}
const counter = createCounter();
counter.increment(); // 1
counter.increment(); // 2
console.log(counter.getCount()); // 2
counter.decrement(); // 1
9.3 Приватні поля в ES2022
У ES2022 були введені приватні поля та методи, які оголошуються з використанням символу #. Приватні поля та методи не можуть бути доступні чи змінені ззовні класу.
Приклад:
- Приватні поля
#nameі#ageоголошені з використанням символу# - Методи
getName,getAge,setNameіsetAgeдозволяють взаємодіяти з приватними полями - Спроба доступу до приватних полів ззовні класу призводить до помилки
class Person {
#name; // приватне поле
#age; // приватне поле
constructor(name, age) {
this.#name = name;
this.#age = age;
}
getName() {
return this.#name;
}
getAge() {
return this.#age;
}
setName(name) {
this.#name = name;
}
setAge(age) {
if (age > 0) {
this.#age = age;
}
}
}
const person = new Person('Alice', 30);
console.log(person.getName()); // "Alice"
console.log(person.getAge()); // 30
person.setName('Bob');
person.setAge(25);
console.log(person.getName()); // "Bob"
console.log(person.getAge()); // 25
console.log(person.#name); // Помилка: приватне поле недоступне
9.4 Приватні методи
Приватні методи також можуть бути оголошені з використанням символу # і бути недоступними ззовні класу.
Приклад:
- Приватне поле
#balanceта приватний метод#logTransactionвикористовуються для управління станом об'єктаBankAccount - Приватний метод
#logTransactionвикликається всередині публічних методівdepositіwithdrawдля запису транзакцій
class BankAccount {
#balance;
constructor(initialBalance) {
this.#balance = initialBalance;
}
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
this.#logTransaction('deposit', amount);
}
}
withdraw(amount) {
if (amount > 0 && amount <= this.#balance) {
this.#balance -= amount;
this.#logTransaction('withdraw', amount);
}
}
getBalance() {
return this.#balance;
}
#logTransaction(type, amount) {
console.log(`Transaction: ${type} ${amount}`);
}
}
const account = new BankAccount(1000);
account.deposit(500); // "Transaction: deposit 500"
console.log(account.getBalance()); // 1500
account.withdraw(200); // "Transaction: withdraw 200"
console.log(account.getBalance()); // 1300
account.#logTransaction('test', 100); // Помилка: приватний метод недоступний
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ