Koska esineitä JavaScript ovat viittauksia arvoja, et voi yksinkertaisesti vain kopioida käyttäen =
. Mutta ei hätää, tässä on 3 tapoja, joilla voit kopioida objektin 👍
# Esineet ovat Viittaus Tyypit
ensimmäinen kysymys voisi olla, miksi en voi käyttää =
. Katsotaan, mitä tapahtuu, jos teemme näin:
const obj = { one: 1, two: 2 };const obj2 = obj;console.log( obj, // {one: 1, two: 2}; obj2, // {one: 1, two: 2};);
toistaiseksi, sekä esine näyttää tuotos sama asia. Ei siis mitään ongelmaa., Mutta katsotaan, mitä tapahtuu, jos me muokata meidän toinen objekti:
const obj2.three = 3;console.log(obj2);// {one: 1, two: 2, three: 3}; <-- ✅console.log(obj);// {one: 1, two: 2, three: 3}; <-- 😱
WTH?! Muutin obj2
mutta miksi oli obj
myös vaikuttaa. Se johtuu siitä, että esineet ovat referenssityyppejä. Joten kun käytät =
, se kopioi osoittimen sen valtaamaan muistiavaruuteen. Vertailutyypeillä ei ole arvoja, ne ovat osoitin muistissa olevaan arvoon.
Jos haluat lisätietoja tästä, Katso Gordonin Zhu-Kello ja Koodikurssi. Se on ilmainen ilmoittautua ja katsella video ”Vertailu esineitä”., Hän antaa siihen mahtavan selityksen.
# 1. Käyttämällä Spread
: tä käyttämällä spread kloonaa objektisi. Huomaa, että tämä on matala kopio. Koska tämä viesti, levitä toimijan kloonaus esineitä on Vaiheessa 4. Se ei siis ole vielä virallisesti määrityksissä. Joten jos aiot käyttää tätä, sinun pitäisi koota se Baabel (tai jotain vastaavaa).
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = { ...food };console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# 2. Objektin Käyttö.määritä
Vaihtoehtoisesti Object.assign
on virallinen julkaisupäivä, ja myös luoda matala kopio kohde.,
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = Object.assign({}, food);console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
Huom tyhjä {}
ensimmäinen argumentti, tässä varmistetaan et muuttua alkuperäisen objektin 👍
# 3. Käyttämällä JSON
Tämä lopullinen tapa antaa sinulle syvä kopio. Tämä on nopea ja likainen tapa kloonata esine. Saat vankempi ratkaisua, haluan suositella käyttäen jotain lodash
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = JSON.parse(JSON.stringify(food));console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# Lodash DeepClone vs JSON
Tässä on kommentti yhteisössä. Kyllä, se oli minun Edellinen viesti, miten Deep kloonata Array ., Mutta ajatus pätee yhä esineisiin.
Alfredo Salzillo : haluaisin sinun huomata, että on olemassa joitakin eroja deepClone ja JSON.stringify / parse.
- JSON.stringify / parse toimii vain numerolla ja merkkijonolla ja objektilla kirjaimellisina ilman funktio-tai Symboliominaisuuksia.
- deepClone work with all types, function and Symbol are copied by reference.
Tässä on esimerkki:
@OlegVaraksin : JSON-menetelmä on ongelmia pyöreä riippuvuudet. Lisäksi kloonatun kohteen ominaisuuksien järjestys voi olla erilainen.,
# Matala Klooni vs Syvä Klooni
Kun käytin levitä ...
kopioi objektin, olen vain luoda matala kopio. Jos array on sisäkkäinen tai moniulotteinen, se ei toimi. Tässä esimerkissä käytämme:
const nestedObject = { flag: '🇨🇦', country: { city: 'vancouver', },};
# Matala Kopio
– Anna on klooni meidän objektin levitä:
const shallowClone = { ...nestedObject };// Changed our cloned objectshallowClone.flag = '🇹🇼';shallowClone.country.city = 'taipei';
Joten muutimme kloonattu esine muuttamalla kaupungin. Katsotaan tuotos.
console.log(shallowClone);// {country: '🇹🇼', {city: 'taipei'}}console.log(nestedObject);// {country: '🇨🇦', {city: 'taipei'}} <-- 😱
matala kopioi ensimmäinen taso on kopioitu, syvemmällä tasolla viitataan.,
# Syvä Kopio
otetaan sama esimerkki, mutta soveltamalla syvä kopioida käyttämällä ”JSON”
Kuten voit nähdä, syvä kopio on todellinen kopio sisäkkäisiä objekteja. Usein aika pinnallinen kopio on tarpeeksi hyvä, et todellakaan tarvitse syvä kopio. Se on kuin naulapyssy ja vasara. Useimmiten vasara on täysin kunnossa. Naulapyssyn käyttäminen joihinkin pieniin taiteisiin ja käsityöhön on usein ylilyönti, vasara on ihan hyvä. Se on kaikki noin käyttämällä oikea työkalu oikeaan työhön 🤓
# Suorituskyky
Valitettavasti en voi kirjoittaa testi levittää, koska se ei ole virallisesti spec vielä., Kuitenkin, otin sen testiin, jotta voit suorittaa sen tulevaisuudessa 😝. Mutta tulos näkyy Object.assign
on paljon nopeampi kuin JSON
.
Testi
# Yhteisön Tulo
# Esine.määritä vs Spread
@d9el: on tärkeää huomata, että objekti.määritä on toiminto, joka muokkaa ja palauttaa kohdeobjektin. Samanthan esimerkiksi käyttämällä seuraavia,
const cloneFood = Object.assign({}, food);
{}
on esine, joka on muutettu., Kohdeobjekti ei ole viitattu millään muuttuja siinä vaiheessa, mutta koska Object.assign
palauttaa kohde, voimme tallentaa tuloksena määritetty objektin cloneFood
muuttuja. Voisimme vaihtaa esimerkissä ylös ja käyttää seuraavia:
const food = { beef: '🌽', bacon: '🥓' };Object.assign(food, { beef: '🥩' });console.log(food);// { beef: '🥩', bacon: '🥓' }
Tietenkin, arvo beef
ruuassa kohde on väärä, niin voimme määrittää oikea arvo beef
käyttäen Object.assign
., Emme ole oikeastaan käyttää palauttaa toiminnon arvoa ollenkaan, mutta me muutetaan meidän kohde, joka meidän on verrattava const food
.
Spread toisaalta on operaattori, joka kopioi yhden kappaleen ominaisuuksia uuteen kappaleeseen., Jos halusimme jäljitellä edellä esimerkiksi käyttämällä levitä muuttaa meidän muuttujan food...
const food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};// TypeError: invalid assignment to const `food'
...
saamme virhe, koska käytämme levitä, kun uusia esineitä, ja siksi on osoitetaan koko uusi objekti food
joka julistettiin const
, joka on laitonta., Joten voimme valita joko julistaa uusi muuttuja pitää uuden objektin, kuten seuraavat:
const food = { beef: '🌽', bacon: '🥓' };const newFood = { ...food, beef: '🥩',};console.log(newFood);// { beef: '🥩', bacon: '🥓' }
tai voimme julistaa food
let
tai var
joka antaisi meille mahdollisuuden määrittää kokonaan uusi esine:
let food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};console.log(food);// { beef: '🥩', bacon: '🥓' }
Kiitos: @d9el
# Syvä Klooni käyttäen Ulkoisia Kirjastoja
# Enemmän Tapoja käyttää Javascriptiä
- @hariharan_d3v :
Object.fromEntries(Object.entries(food))
klooneja kohde.
Vastaa