Câmpuri și Metode Private în Clase (#) în JavaScript

Obiecte ECMAScript 2022 (ES13)

Încapsulare strictă la nivel de motor V8 în JavaScript: declararea variabilelor și metodelor private cu prefixul #, complet inaccesibile din exteriorul clasei.

Sintaxă
class ContBancar { #balanta = 0; #valideaza() {} }

Timp de peste două decenii, JavaScript nu a avut suport nativ pentru proprietăți cu adevărat private în clase. Dezvoltatorii foloseau convenția vizuală cu underscore (ex: this._parola = 'secret'), însă acele proprietăți rămâneau complet publice și puteau fi citite sau modificate din exteriorul instanței.

Începând cu ECMAScript 2022 (ES13), JavaScript suportă câmpuri și metode cu adevărat private prin prefixarea numelui cu simbolul hash (#). Această intimitate este impusă direct de motorul intern al browserului (V8 / SpiderMonkey): proprietățile # nu pot fi accesate, inspectate și nici măcar detectate prin Object.keys() sau for...in din afara corpului clasei.

Implementarea unui Cont Bancar securizat cu câmpuri private
class ContBancar {
    // 1. Declararea câmpului privat (#)
    #sold = 0;
    
    // Câmp privat static (partajat doar între metodele clasei)
    static #numarConturi = 0;

    constructor(titular, soldInitial = 0) {
        this.titular = titular; // Public
        this.#sold = soldInitial; // Privat
        ContBancar.#numarConturi++;
    }

    // 2. Metodă privată (poate fi apelată doar intern)
    #auditeazaTranzactie(tip, suma) {
        console.log(`[AUDIT] ${this.titular}: ${tip} de ${suma} RON`);
    }

    // Metode publice pentru acces controlat (Getter / Setter)
    depune(suma) {
        if (suma <= 0) throw new Error("Suma trebuie să fie pozitivă.");
        this.#sold += suma;
        this.#auditeazaTranzactie("Depunere", suma);
    }

    get soldDisponibil() {
        return this.#sold;
    }
}

const cont = new ContBancar('Ion Popescu', 500);
cont.depune(250);
console.log(cont.soldDisponibil); // 750

// Încercarea de accesare directă a câmpului privat:
// console.log(cont.#sold); 
// SyntaxError: Private field '#sold' must be declared in an enclosing class

Operatorul in pentru verificarea câmpurilor private

Poți verifica în mod sigur dacă un obiect deține un anumit câmp privat folosind operatorul in:

if (#sold in obiect) {
    // Obiectul este o instanță validă a clasei ContBancar
}