Clase și prototipuri
class, câmpuri private, getteri, extends și ce e sub capotă.
Actualizat
Ce este o clasă
O clasă e un șablon pentru a crea obiecte de același fel. Descrie o dată ce date (proprietăți) și ce comportament (metode) au; apoi creezi oricâte instanțe cu new.
class Account {
constructor(owner) { // rulează la new — inițializează obiectul
this.owner = owner
this.balance = 0
}
deposit(amount) { // metodă — comportament comun tuturor conturilor
this.balance += amount
}
}
const a = new Account('Ana') // instanță
const b = new Account('Ion') // altă instanță, cu datele ei
a.deposit(100)Analogie: clasa e matrița, instanțele sunt prăjiturile.
Părțile unei clase — tipuri de membri
| Membru | Sintaxă | Aparține | Când |
|---|---|---|---|
| câmp public | count = 0 |
fiecărei instanțe | date vizibile din afară |
| câmp privat | #balance = 0 |
fiecărei instanțe, inaccesibil din afară | date interne, protejate |
| metodă | deposit() {} |
partajată de toate instanțele | comportament |
| getter / setter | get total() {} / set total(v) {} |
instanței | valoare calculată citită ca proprietate |
| static | static from(json) {} |
clasei, nu instanței | fabrici, constante, helpere |
class Account {
#balance = 0 // privat — acc.#balance dă SyntaxError
static currency = 'RON' // Account.currency
constructor(owner) { this.owner = owner }
deposit(amount) {
if (amount <= 0) throw new Error('Sumă invalidă')
this.#balance += amount
return this // permite chaining: acc.deposit(1).deposit(2)
}
get balance() { return this.#balance } // acc.balance — fără paranteze
static fromJSON({ owner }) { return new Account(owner) }
}Moștenire
extends creează o clasă care preia tot de la alta și adaugă sau schimbă ceva:
class Savings extends Account {
constructor(owner, rate) {
super(owner) // apelează constructorul părintelui — obligatoriu înainte de this
this.rate = rate
}
addInterest() { this.deposit(this.balance * this.rate) }
}Prototipuri — ce e sub capotă
Clasele sunt „zahăr sintactic” peste prototipuri. Fiecare obiect are o legătură ascunsă spre alt obiect (prototipul lui). Când ceri o proprietate care nu există pe obiect, JS o caută în prototip, apoi în prototipul prototipului — prototype chain.
a.deposit // nu e pe a, e găsită pe Account.prototype
Object.getPrototypeOf(a) === Account.prototype // true
a instanceof Account // true — Account.prototype e în lanțDe-asta metodele sunt partajate (un singur deposit în memorie pentru toate conturile), iar [].map funcționează pe orice array (e pe Array.prototype).
Clase vs funcții + obiecte
| Clase | Funcții + obiecte simple | |
|---|---|---|
| Stare internă protejată | #private |
closure |
| Moștenire | extends |
compoziție (combini funcții) |
this |
da, cu capcanele lui | nu e nevoie |
| În React modern | doar error boundaries | totul: componente, hooks |
Când folosești clase în frontend
- Da: erori custom (
class HttpError extends Error), client API / SDK, structuri de date (o coadă, un cache), integrare cu librării bazate pe clase. - Nu: componente React (azi sunt funcții), date simple (un obiect literal ajunge).
- Preferă compoziția (bucăți mici combinate) în locul ierarhiilor adânci de moștenire —
A extends B extends C extends Ddevine greu de schimbat.
Pe scurt
- Clasă = șablon;
newcreează instanțe;constructorinițializează. - Câmpuri
#private, getteri,static,extends+super. - Sub capotă: prototipuri. În React, aproape mereu funcții.