Interview question
How do private class fields (#field) work in JavaScript? JavaScript में private class fields (#field) कैसे काम करते हैं?
Answer
Private fields, prefixed with #, are truly inaccessible from outside the class - unlike the old convention of prefixing with an underscore, which was only a naming convention, not real privacy.
class Counter {
#count = 0; // private field, initialized directly
#step; // private field, no default
constructor(step = 1) {
this.#step = step;
}
increment() {
this.#count += this.#step;
return this.#count;
}
get value() {
return this.#count;
}
}
const counter = new Counter(5);
console.log(counter.increment()); // 5
console.log(counter.value); // 5
// Truly inaccessible from outside
console.log(counter.count); // undefined - not #count, just a regular missing property
// console.log(counter.#count); // SyntaxError - private fields can't even be referenced outside the class
// Compare to old convention (NOT truly private, just a naming signal)
class OldStyleCounter {
constructor() {
this._count = 0; // underscore convention - developers SHOULD not touch it, but CAN
}
}
const old = new OldStyleCounter();
old._count = 999; // works fine - no real protection
// Private methods also exist
class Calculator {
#history = [];
add(a, b) {
const result = a + b;
this.#logOperation('add', result); // calling a private method
return result;
}
#logOperation(type, result) { // private method - # prefix
this.#history.push({ type, result });
}
getHistory() {
return [...this.#history]; // controlled read-only access
}
}
// Static private fields for class-level private state
class IdGenerator {
static #nextId = 1;
static generate() {
return IdGenerator.#nextId++;
}
}
console.log(IdGenerator.generate()); // 1
console.log(IdGenerator.generate()); // 2Private fields, # prefix के साथ, class के बाहर से truly inaccessible होते हैं - पुरानी underscore convention से अलग, जो सिर्फ naming convention थी, real privacy नहीं।
class Counter {
#count = 0; // private field
#step;
constructor(step = 1) {
this.#step = step;
}
increment() {
this.#count += this.#step;
return this.#count;
}
get value() {
return this.#count;
}
}
const counter = new Counter(5);
console.log(counter.increment()); // 5
console.log(counter.value); // 5
// Truly inaccessible
console.log(counter.count); // undefined
// counter.#count; // SyntaxError
// पुरानी convention (real privacy नहीं)
class OldStyleCounter {
constructor() {
this._count = 0; // सिर्फ convention
}
}
const old = new OldStyleCounter();
old._count = 999; // काम करता है, कोई protection नहीं
// Private methods भी होते हैं
class Calculator {
#history = [];
add(a, b) {
const result = a + b;
this.#logOperation('add', result);
return result;
}
#logOperation(type, result) {
this.#history.push({ type, result });
}
getHistory() {
return [...this.#history];
}
}
// Static private fields
class IdGenerator {
static #nextId = 1;
static generate() {
return IdGenerator.#nextId++;
}
}
console.log(IdGenerator.generate()); // 1Was this answer clear?