mivel a JavaScript objektumai referenciák, nem lehet egyszerűen csak másolni a =
. De ne aggódjon, itt van 3 módszer egy objektum klónozására 👍
# az objektumok Referenciatípusok
az első kérdés lehet, miért nem használhatom a =
. Lássuk, mi történik, ha ezt tesszük:
const obj = { one: 1, two: 2 };const obj2 = obj;console.log( obj, // {one: 1, two: 2}; obj2, // {one: 1, two: 2};);
eddig mindkét objektum úgy tűnik, hogy ugyanazt adja ki. Tehát nem probléma, igaz., De lássuk, mi történik, ha szerkesztjük a második objektumunkat:
const obj2.three = 3;console.log(obj2);// {one: 1, two: 2, three: 3}; <-- ✅console.log(obj);// {one: 1, two: 2, three: 3}; <-- 😱
WTH?! Megváltoztattam obj2
de miért volt obj
is érintett. Ennek oka az, hogy az objektumok referenciatípusok. Tehát ,ha a=
– ot használja, a mutatót átmásolta az általa elfoglalt memóriaterületre. A referenciatípusok nem tartalmaznak értékeket, hanem a memóriában lévő érték mutatói.
Ha többet szeretne megtudni erről, nézze meg Gordon Zhu óráját és Kódtanfolyamát. Ez ingyenes, hogy beiratkozik, majd nézze meg a videót “összehasonlítás tárgyak”., Szuper félelmetes magyarázatot ad rá.
# 1. A Spread
használata spread klónozza az objektumot. Vegye figyelembe, hogy ez egy sekély példány lesz. Ettől a poszttól kezdve az objektumok klónozására szolgáló spread operátor a 4. szakaszban van. Tehát hivatalosan még nem szerepel a specifikációkban. Tehát ha ezt használná, akkor össze kell állítania a Babellel (vagy valami hasonlóval).
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = { ...food };console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# 2. Objektum Használata.hozzárendelés
Alternatív megoldásként aObject.assign
a hivatalos kiadásban található, valamint létrehoz egy sekély példányt az objektumról.,
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = Object.assign({}, food);console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
Megjegyzés Az üres {}
mint az első érv, ez biztosítja, hogy ne mutálja az eredeti objektumot 👍
# 3. A JSON használata
Ez a végső módszer mély másolatot ad. Most megemlítem, hogy ez egy gyors és piszkos módszer egy tárgy mély klónozására. Lodash lodash
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = JSON.parse(JSON.stringify(food));console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# Lodash DeepClone vs JSON
itt van egy megjegyzés a közösségtől. Igen, ez volt az előző post, Hogyan mély klón tömb ., De az ötlet még mindig tárgyakra vonatkozik.
Alfredo Salzillo: szeretném megjegyezni, hogy vannak különbségek deepClone és JSON között.stringify / elemzés.
- JSON.stringify / parse csak akkor működik, szám, String és objektum szó nélkül függvény vagy szimbólum tulajdonságait.
- a deepClone minden típussal, funkcióval és szimbólummal végzett munkát referenciaként másol.
Íme egy példa:
@OlegVaraksin: a JSON metódusnak körkörös függőségekkel kapcsolatos problémái vannak. Ezenkívül a klónozott objektum tulajdonságainak sorrendje eltérő lehet.,
# Shallow Clone vs Deep Clone
amikor spread ...
egy objektum másolásához csak egy sekély példányt készítek. Ha a tömb beágyazott vagy többdimenziós, akkor nem fog működni. Itt van a példa fogjuk használni:
const nestedObject = { flag: '🇨🇦', country: { city: 'vancouver', },};
# sekély másolat
klónozzuk objektumunkat spread segítségével:
const shallowClone = { ...nestedObject };// Changed our cloned objectshallowClone.flag = '🇹🇼';shallowClone.country.city = 'taipei';
tehát megváltoztattuk klónozott objektumunkat a város megváltoztatásával. Lássuk a kimenetet.
console.log(shallowClone);// {country: '🇹🇼', {city: 'taipei'}}console.log(nestedObject);// {country: '🇨🇦', {city: 'taipei'}} <-- 😱
a sekély másolat azt jelenti, hogy az első szintet lemásolják, a mélyebb szintekre hivatkoznak.,
# Deep Copy
vegyük ugyanazt a példát, de alkalmazzunk egy mély másolatot a “JSON”
használatával, amint láthatja, a mély másolat valódi másolat beágyazott objektumokhoz. Gyakran idő sekély másolat elég jó, akkor nem igazán kell egy mély példányt. Olyan, mint egy szögpisztoly vs egy kalapács. Legtöbbször a kalapács tökéletesen rendben van. A körömpisztoly használata néhány kis művészethez és kézműveshez gyakran túlzás, a kalapács csak finom. Ez arról szól, hogy a megfelelő eszközt használja a megfelelő munkához 🤓
# teljesítmény
sajnos nem tudok tesztet írni a spread számára, mert még nem hivatalosan a spec-ben., Ennek ellenére bevittem a tesztbe, így a jövőben futtatható 😝. De az eredmény azt mutatja, hogy a Object.assign
sokkal gyorsabb, mint a JSON
.
teljesítményteszt
# közösségi bemenet
# objektum.hozzárendelése vs Spread
@d9el: fontos megjegyezni, hogy az objektum.a hozzárendelés olyan függvény, amely módosítja és visszaadja a célobjektumot. Samantha példájában a következő:
const cloneFood = Object.assign({}, food);
{}
a módosított objektum., A célobjektumra egyetlen változó sem hivatkozik ezen a ponton, de mivel aObject.assign
visszaadja a célobjektumot, a kapott hozzárendelt objektumot acloneFood
változóba tudjuk tárolni. A példát fel tudjuk váltani, és a következőket használhatjuk:
const food = { beef: '🌽', bacon: '🥓' };Object.assign(food, { beef: '🥩' });console.log(food);// { beef: '🥩', bacon: '🥓' }
nyilvánvaló, hogy a beef
értéke az élelmiszer-objektumunkban helytelen, így hozzárendelhetjük a beef
helyes értékét a Object.assign
., Valójában egyáltalán nem használjuk a funkció visszaadott értékét, de módosítjuk a célobjektumunkat, amelyre a const food
hivatkozással hivatkoztunk.a
Spread viszont egy operátor, amely egy objektum tulajdonságait másolja egy új objektumba., Ha meg akarta ismételni a fenti példa használata elterjedt, hogy módosítsa a változó food...
const food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};// TypeError: invalid assignment to const `food'
...
kapunk hibaüzenetet, mert elterjedt, amikor új objektumok létrehozása, ezért hozzárendelése egy teljesen új objektum food
nyilvánított a const
, ami illegális., Így mi sem dönt, hogy állapítsa meg egy új változó, hogy tartsa az új tárgy, mint a következő:
const food = { beef: '🌽', bacon: '🥓' };const newFood = { ...food, beef: '🥩',};console.log(newFood);// { beef: '🥩', bacon: '🥓' }
vagy lehet nyilatkozni food
a let
vagy var
, amely lehetővé tenné számunkra, hogy rendeljen egy teljesen új objektum:
let food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};console.log(food);// { beef: '🥩', bacon: '🥓' }
Köszi: @d9el
# Mély Klón segítségével Külső Könyvtárak
# Több Módon használja a JavaScript
- @hariharan_d3v :
Object.fromEntries(Object.entries(food))
klónok a tárgy.
Vélemény, hozzászólás?