Инкапсуляция: приватные поля и методы (#)

Почему инкапсуляция — это круто? 🔒

Представь, что пишешь кофеварку. У неё есть:

  1. Кнопка включения — публичный метод
  2. Логика нагрева воды — приватный метод
  3. Датчик температуры — приватное поле

Без инкапсуляции пользователь мог бы сжечь кофеварку, изменяя температуру напрямую! Именно поэтому мы скрываем "внутреннюю кухню" объектов.

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;
    }
  }
}

Зачем это нужно? 🧐

  1. Защита данных — никто не изменит #password напрямую
  2. Контроль изменений — валидация через методы
  3. Упрощение рефакторинга — меняем внутреннюю логику, не трогая API
  4. Чистый интерфейс — пользователь видит только нужные методы

💡 Интересный факт: в 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);  // Берет из кэша

Ограничения и подводные камни ⚠️

  1. Наследование — приватные поля недоступны в подклассах
  2. Доступ через this — даже внутри класса нужно писать this.#field
  3. Статические приватные — используют тот же синтаксис: static #count = 0
class Parent {
  #secret = 'parent data';

  getSecret() {
    return this.#secret;
  }
}

class Child extends Parent {
  tryToGetSecret() {
    // return this.#secret;  // Ошибка!
    return this.getSecret();  // Работает
  }
}
Скрыть рекламу навсегда

🎥 YouTube: программирование простым языком

Канал, где я спокойно и по шагам объясняю сложные темы — без заумных терминов и лишней теории.

Подходит, если раньше «не заходило», но хочется наконец понять.

▶️ Смотреть курсы на YouTube