Fordi objekter i JavaScript er referanser verdier, kan du ikke bare kopiere ved hjelp av =
. Men ingen grunn til bekymring, her er 3 måter for deg å klone et objekt 👍
# Objekter Referanse Typer
Din første spørsmålet kan være, hvorfor kan jeg ikke bruke =
. La oss se hva som skjer hvis vi gjør det:
const obj = { one: 1, two: 2 };const obj2 = obj;console.log( obj, // {one: 1, two: 2}; obj2, // {one: 1, two: 2};);
Så langt, både objekt ser ut til å få den samme tingen. Så ikke noe problem, ikke sant., Men la oss se hva som skjer hvis vi redigerer våre andre objekt:
const obj2.three = 3;console.log(obj2);// {one: 1, two: 2, three: 3}; <-- ✅console.log(obj);// {one: 1, two: 2, three: 3}; <-- 😱
WTH?! Jeg endret obj2
men hvorfor var obj
også berørt. Det er fordi Objektene er referanse typer. Så når du bruker =
, det kopieres pekeren til plassen hotellet ligger. Referanse typer ikke hold verdier, de er en peker til verdien i minnet.
Hvis du ønsker å lære mer om dette, sjekk ut Gordon ‘ s Watch Zhu og Kode kurs. Det er gratis å registrere og se videoen «Sammenlignet med objekter»., Han gir en super awesome forklaring på det.
# 1. Ved hjelp av Spredt
ved Hjelp av spredningen vil klone din objektet. Dette vil være en grunn kopi. Så med dette innlegget, spredning operatør for kloning objekter er i Fase 4. Så det er ikke offisielt i spesifikasjonene ennå. Så hvis du skulle bruke dette, ville du trenger å kompilere det med Babel (eller noe lignende).
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = { ...food };console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# 2. Ved Hjelp Av Objektet.tilordne
Alternativt Object.assign
er i den offisielle utgitt, og vil også lage en liten kopi av objektet.,
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = Object.assign({}, food);console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
Merk tom {}
som første argument, dette vil sikre at du ikke mutere det originale objektet 👍
# 3. Ved hjelp av JSON
Denne siste måten vil gi deg en dyp kopi. Nå vil jeg nevne, dette er en rask og skitten måte dyp kloning av et objekt. For en mer robust løsning, ville jeg anbefale å bruke noe som lodash
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = JSON.parse(JSON.stringify(food));console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# Lodash DeepClone vs JSON
Her er en kommentar fra fellesskapet. Ja, det var for mitt forrige innlegg, Hvor Dypt Klone en Matrise ., Men ideen gjelder fortsatt, til objekter.
Alfredo Salzillo : jeg vil at du skal være oppmerksom på at det er noen forskjeller mellom deepClone og JSON.stringify/parse.
- JSON.stringify/parse bare jobbe med Tall og Streng og Objekt bokstavelig uten funksjon eller Symbol egenskaper.
- deepClone arbeid med alle typer, funksjon og Symbol er kopiert av referanse.
Her er et eksempel:
@OlegVaraksin : JSON metoden har problemer med sirkulære avhengigheter. Videre rekkefølgen av egenskaper i klonet objekt kan være forskjellig.,
# Grunne Klone vs Dyp Klone
Når jeg brukte spre ...
for å kopiere et objekt, jeg er bare opprette en grunn kopi. Hvis matrise er nestet eller multi-dimensjonal, det vil ikke fungere. Her er vårt eksempel vil vi bruke:
const nestedObject = { flag: '🇨🇦', country: { city: 'vancouver', },};
# grunn Kopi
La oss klone våre objektet ved hjelp av spredt:
const shallowClone = { ...nestedObject };// Changed our cloned objectshallowClone.flag = '🇹🇼';shallowClone.country.city = 'taipei';
Slik at vi har endret våre klonet objekt ved å endre byen. La oss se resultatet.
console.log(shallowClone);// {country: '🇹🇼', {city: 'taipei'}}console.log(nestedObject);// {country: '🇨🇦', {city: 'taipei'}} <-- 😱
En grunn kopi betyr det første nivået er kopiert, dypere nivåer er det refereres til.,
# Dyp Kopi
La oss ta samme eksempel, men å bruke en dyp kopi ved hjelp av «JSON»
Som du kan se, den dype copy er en sann kopi for nestede objekter. Ofte tid på grunn kopi er god nok, er du ikke virkelig trenger en dyp kopi. Det er som en spikerpistol vs en hammer. Mesteparten av tiden hammer er helt greit. Ved hjelp av en spikerpistol for noen små kunst og håndverk er ofte tilfelle en overkill, en hammer er bare fint. Det handler om å bruke rett verktøy til rett jobb 🤓
# Ytelse
Dessverre, jeg kan ikke skrive en test for å spre seg fordi det er ikke offisielt i spec ennå., Likevel, jeg har tatt det med i testen, slik at du kan kjøre den i fremtiden 😝. Men resultatet viser Object.assign
er en mye raskere enn JSON
.
Ytelse Test
# Samfunnet Inndata
# Objekt.tilordne vs Spre
@d9el : Det er viktig å merke seg at Objektet.tilordne er en funksjon som endrer og returnerer målobjekt. I Samantha eksempel ved hjelp av følgende,
const cloneFood = Object.assign({}, food);
{}
er objektet som er endret., Målet målet er ikke referert til av noen variable på det tidspunktet, men fordi Object.assign
returnerer målet objekt, er vi i stand til å lagre den resulterende tilordnet objektet i cloneFood
variabel. Vi kunne bytte til vårt eksempel opp og bruke følgende:
const food = { beef: '🌽', bacon: '🥓' };Object.assign(food, { beef: '🥩' });console.log(food);// { beef: '🥩', bacon: '🥓' }
Selvfølgelig, verdien av beef
i maten vår objekt som er galt, slik at vi kan gi den riktige verdien av beef
med Object.assign
., Vi er ikke egentlig bruke verdien som returneres av funksjonen i det hele tatt, men vi endrer vårt mål objekt som vi har referert til med const food
.
Spredt på den annen side er det en operatør som kopier egenskaper av ett objekt til et nytt objekt., Hvis vi ønsket å kopiere eksemplet ovenfor bruker spres til å endre våre variable food...
const food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};// TypeError: invalid assignment to const `food'
...
vi få en feil, fordi vi bruker spredning når du oppretter nye objekter og derfor er tilordne et helt nytt objekt til food
som ble deklarert med const
, som er ulovlig., Så kan vi enten velge å erklære en ny variabel for å holde våre nye objektet i, som følgende:
const food = { beef: '🌽', bacon: '🥓' };const newFood = { ...food, beef: '🥩',};console.log(newFood);// { beef: '🥩', bacon: '🥓' }
eller vi kan erklære food
med let
eller var
som ville tillate oss å tilordne en helt ny objekt:
let food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};console.log(food);// { beef: '🥩', bacon: '🥓' }
Takk: @d9el
# Dyp Klone bruk av Eksterne Biblioteker
# Flere Måter ved hjelp av JavaScript
- @hariharan_d3v :
Object.fromEntries(Object.entries(food))
kloner objektet.
Legg igjen en kommentar