Modern JS classes have real privacy and computed properties โ the features that make encapsulation answers concrete in interviews.
The full toolkit in one class
class Student {
#marks = []; // private โ hard privacy, not convention
static school = "Anna University"; // on the class, not instances
constructor(name) { this.name = name; }
addMark(m) {
if (m < 0 || m > 100) throw new RangeError("Invalid mark");
this.#marks.push(m); // validation guards the private state
}
get average() { // computed โ accessed like a property
if (!this.#marks.length) return 0;
return this.#marks.reduce((a,b) => a+b) / this.#marks.length;
}
set nickname(v) { // intercept assignment
if (v.length < 2) throw new Error("Too short");
this._nickname = v.trim();
}
static compare(a, b) { return b.average - a.average; }
}
const s = new Student("Priya");
s.addMark(88);
s.average; // 88 โ no parentheses, it's a getter
s.#marks; // โ SyntaxError โ genuinely private
Student.school; // static access
students.sort(Student.compare);When to reach for each
- #private: anything external code shouldn't touch โ the real encapsulation answer
- get: derived values that read like data (fullName, total, isValid)
- set: validation/normalization on assignment โ use sparingly, hidden side effects surprise readers
- static: factories, comparators, constants tied to the class