Private field khai báo bằng tiền tố #, chỉ truy cập được bên trong thân class.
javascript
class Account {
#balance = 0 // private field
static #count = 0 // private static
constructor(initial) {
this.#balance = initial
Account.#count++
}
#validate(amount) { // private method
return amount > 0 && amount <= this.#balance
}
withdraw(amount) {
if (!this.#validate(amount)) throw new Error('Số tiền không hợp lệ')
this.#balance -= amount
}
get balance() { return this.#balance }
}
const acc = new Account(100)
acc.balance // 100 — qua getter
acc.#balance // SyntaxError khi biên dịch — ngoài thân classĐây là private thật ở tầng engine, khác hẳn quy ước _name:
javascript
Object.keys(acc) // [] — không thấy #balance
JSON.stringify(acc) // '{}' — không serialize
Object.getOwnPropertyNames(acc) // [] — không có cách nào lấy raKiểm tra một object có phải instance có field đó không — cú pháp in cho private field (ES2022):
javascript
static isAccount(obj) { return #balance in obj }Lưu ý về loại lỗi: viết acc.#balance ở ngoài class là SyntaxError lúc phân tích cú pháp, không phải lỗi runtime. Còn truy cập this.#balance trên một object không phải instance của class (vd sau khi call sang object khác) mới ném TypeError lúc chạy.
Lưu ý 2: #balance không kế thừa xuống subclass — lớp con không đọc được private field của lớp cha, phải qua getter/method công khai.