Инкапсуляция: приватные поля и методы (#)
Почему инкапсуляция — это круто? 🔒
Представь, что пишешь кофеварку. У неё есть:
- Кнопка включения — публичный метод
- Логика нагрева воды — приватный метод
- Датчик температуры — приватное поле
Без инкапсуляции пользователь мог бы сжечь кофеварку, изменяя температуру напрямую! Именно поэтому мы скрываем "внутреннюю кухню" объектов.
class CoffeeMachine {
#waterTemperature = 20; // Приватное поле
turnOn() {
this.#heatWater();
console.log("Ваш кофе готовится!");
}
#heatWater() { // Приватный метод
this.#waterTemperature = 92;
}
}
🔥 Совет от Данилы Бежина: "Приватные поля — как нижнее бельё объекта. Показывать его не принято, но без него система не работает!"
Синтаксис приватности в ES2022+ 🆕
Символ # перед именем делает поле/метод приватным. Важные правила:
| Особенность | Пример | Доступность |
|---|---|---|
| Приватное поле | #secret = 42 |
Только внутри класса |
| Приватный метод | #secureMethod() |
Только внутри класса |
| Публичное поле | publicData |
Открытый доступ |
class BankAccount {
#pin = '1234'; // Приватное поле
constructor(balance) {
this.balance = balance; // Публичное поле
}
#verifyPin(pin) { // Приватный метод
return this.#pin === pin;
}
withdraw(amount, pin) {
if (this.#verifyPin(pin)) {
this.balance -= amount;
}
}
}
Зачем это нужно? 🧐
- Защита данных — никто не изменит
#passwordнапрямую - Контроль изменений — валидация через методы
- Упрощение рефакторинга — меняем внутреннюю логику, не трогая API
- Чистый интерфейс — пользователь видит только нужные методы
💡 Интересный факт: в JavaScript приватность реализована на уровне синтаксиса — попытка доступа к
#fieldснаружи выбросит ошибку до выполнения кода!
Реальный пример: кэширующий калькулятор 🧮
class SmartCalculator {
#cache = new Map(); // Приватный кэш
square(x) {
if (this.#cache.has(x)) {
console.log('Из кэша:', x);
return this.#cache.get(x);
}
const result = x * x;
this.#cache.set(x, result);
return result;
}
}
const calc = new SmartCalculator();
calc.square(5); // Вычисляет
calc.square(5); // Берет из кэша
Ограничения и подводные камни ⚠️
- Наследование — приватные поля недоступны в подклассах
- Доступ через
this— даже внутри класса нужно писатьthis.#field - Статические приватные — используют тот же синтаксис:
static #count = 0
class Parent {
#secret = 'parent data';
getSecret() {
return this.#secret;
}
}
class Child extends Parent {
tryToGetSecret() {
// return this.#secret; // Ошибка!
return this.getSecret(); // Работает
}
}