Encapsulation and Security

A well-designed class hides its internal details from the outside world so they can't be accidentally broken. JavaScript provides two levels of this protection.

1. Protected (Convention)

Properties starting with underscore _name. Technically accessible from outside, but developers agree not to touch them — it's a " handle with care " signal.

class BankAccount {
  constructor(balance) {
    this._balance = balance; // "protected" by convention
  }

  deposit(amount) {
    if (amount <= 0) throw new Error('Amount must be positive');
    this._balance += amount;
  }
}

2. Private Fields (True Protection)

Properties starting with # are enforced by the JavaScript engine itself — truly inaccessible outside the class.

class CoffeeMachine {
  #waterAmount = 0;

  setWaterAmount(value) {
    if (value < 0) throw new Error('Negative water!');
    this.#waterAmount = value;
  }

  getWaterAmount() { return this.#waterAmount; }
}

const machine = new CoffeeMachine();
machine.#waterAmount = 100; // SyntaxError: private field access
Caution

Private fields are the strongest data protection available at the language level. Unlike _underscore convention, they are truly enforced — you cannot bypass them with obj['#field'] or Object.keys().