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().