webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Unelte
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Formulare
  12. 12Date și backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animații
  16. 16Testare
  17. 17Arhitectură
JavaScript · Lecția 10 din 17

Referințe și imutabilitate

Valoare vs referință, update-uri imutabile, shallow vs deep copy.

Actualizat

Ce înseamnă valoare și referință

Când atribui o valoare unei variabile, JS face unul din două lucruri, în funcție de tip:

Prin valoare Prin referință
Tipuri primitive: string, number, boolean, null, undefined obiecte, array-uri, funcții
Ce se copiază valoarea însăși adresa spre aceeași valoare din memorie
Efect două copii independente două nume pentru același obiect
let a = 1
let b = a
b = 2
a          // 1 — copii independente

const x = { count: 1 }
const y = x            // y indică același obiect ca x
y.count = 2
x.count    // 2 — e același obiect!

Analogie: primitivele sunt ca o fotocopie a unei foi; obiectele sunt ca un link spre un Google Doc — trimiți linkul, nu documentul.

Comparația urmează aceeași regulă

'a' === 'a'            // true — compară valorile
{ a: 1 } === { a: 1 }  // false — două obiecte diferite, adrese diferite
const o = {}; o === o  // true — aceeași adresă

Ce este imutabilitatea

Imutabil = nu modifici obiectul existent, ci creezi unul nou cu modificarea. Opusul e mutația — modificarea pe loc.

// mutație
user.age = 31

// imutabil
const updated = { ...user, age: 31 }

De ce contează — mai ales în React

React decide dacă să re-randeze comparând state-ul vechi cu cel nou prin referință (Object.is). Dacă modifici obiectul pe loc, referința e aceeași → React crede că nimic nu s-a schimbat → UI-ul nu se actualizează.

// ✗ mutație: aceeași referință, nicio re-randare
todos.push(newTodo)
setTodos(todos)

// ✓ array nou
setTodos([...todos, newTodo])

Alte avantaje: poți compara rapid „s-a schimbat?”, ai istoric (undo), nu ai efecte ascunse între părți din cod care partajează același obiect.

Cheat-sheet: update-uri imutabile

Operație Array Obiect
adaugă [...arr, x] { ...obj, key: v }
șterge arr.filter(x => x.id !== id) const { key, ...rest } = obj
modifică unul arr.map(x => x.id === id ? { ...x, done: true } : x) { ...obj, key: v }
sortează arr.toSorted(fn) —
la index arr.with(i, v) —
nested — { ...obj, address: { ...obj.address, city } }

Shallow copy vs deep copy

Shallow (de suprafață) Deep (completă)
Cum { ...obj }, [...arr], Object.assign structuredClone(obj)
Ce copiază doar primul nivel; obiectele din interior rămân partajate tot, la orice adâncime
Cost mic mai mare
Când update-uri de state (copiezi doar ce schimbi) când chiar ai nevoie de o copie independentă
const copy = { ...user }
copy.address.city = 'Iași'     // ✗ modifică și user.address — e același obiect

const deep = structuredClone(user)
deep.address.city = 'Iași'     // ✓ user rămâne neatins

JSON.parse(JSON.stringify(x)) — hack-ul vechi; pierde Date, Map, undefined, funcții. Folosește structuredClone.

Object.freeze

Object.freeze(obj) blochează modificările (doar primul nivel). Util pentru constante de configurare, ca să prinzi mutații accidentale.

Pe scurt

  • Primitivele se copiază prin valoare, obiectele prin referință.
  • Imutabil = creezi obiect nou în loc să-l modifici; obligatoriu pentru state în React.
  • Spread copiază doar primul nivel; structuredClone pentru copie completă.

Surse oficiale

Exerciții

Ți-a fost utilă pagina?

Un click — fără cont.