Am pierdut azi vreo două ore – și nu doar eu, m-a ajutat și un amic la treaba asta! – să mă prind cum se copiază referințele unei variabile sau a unui obiect.
Am plecat de la premisa – adevărată, de altfel – că .map()
și .filter()
sunt funcții pure. Adică orice se întâmplă în funcții rămâne în funcții.
Aveam obiectul ăsta:
const obj = [{foo: 1}, {foo: 2}, {foo:3}]
Îl filtram:
console.log(obj.filter(o => o.foo > 2))
Și funcționa corespunzător. Dar la map()
lucrurile păreau că o se duc în zona crepusculară:
obj.map(o => { o.bar = false; return o; })
Mai exact, codul ăsta de mai sus modifica variabila obj
!
Ore mai târziu – în care am și refactorizat chestii – ne-au adus aici:
When an object variable is copied, the reference is copied, but the object itself is not duplicated.
sursa
Motherfucker!
Varianta corectă este, deci:
obj.map(o => { return { ...o, bar: false}; })
mi se pare foarte stupidă decizia de limbaj de a nu face const
imutabil…
Aceeași chestie e valabila si la arrays. Btw nici puncte puncte ala nu e infailibil, daca ai o proprietate care iti pointeaza catre un obiect, iti va întoarce tot obiectul ala (sau mai bine zis referinta catre el). Asa ca daca ai structuri mai complexe si vrei sa fii cu adevărat safe cauta o librărie de deep cloning.
Poate te ajuta https://www.geeksforgeeks.org/lodash-_-clonedeep-method/