# 3 Modi per clonare oggetti in JavaScript

postato in: Articles | 0

Poiché gli oggetti in JavaScript sono valori di riferimento, non puoi semplicemente copiare usando=. Ma non preoccuparti, ecco 3 modi per clonare un oggetto

# Gli oggetti sono tipi di riferimento

La tua prima domanda potrebbe essere, perché non posso usare=. Vediamo cosa succede se lo facciamo:

const obj = { one: 1, two: 2 };const obj2 = obj;console.log( obj, // {one: 1, two: 2}; obj2, // {one: 1, two: 2};);

Finora, entrambi gli oggetti sembrano produrre la stessa cosa. Quindi nessun problema, giusto., Ma vediamo cosa succede se modifichiamo il nostro secondo oggetto:

const obj2.three = 3;console.log(obj2);// {one: 1, two: 2, three: 3}; <-- ✅console.log(obj);// {one: 1, two: 2, three: 3}; <-- 😱

WTH?! Ho cambiato obj2 ma perché è stato influenzato anche obj. Questo perché gli oggetti sono tipi di riferimento. Quindi, quando usi =, ha copiato il puntatore nello spazio di memoria che occupa. I tipi di riferimento non contengono valori, sono un puntatore al valore in memoria.

Se vuoi saperne di più su questo, dai un’occhiata al corso Zhu Watch e Code di Gordon. E ‘ libero di iscriversi e guardare il video “Confronto con gli oggetti”., Dà una spiegazione super impressionante su di esso.

# 1. Usando Spread

Usando spread clonerai il tuo oggetto. Nota che questa sarà una copia superficiale. A partire da questo post, l’operatore di diffusione per la clonazione di oggetti è nella fase 4. Quindi non è ancora ufficialmente nelle specifiche. Quindi, se dovessi usarlo, dovresti compilarlo con Babel (o qualcosa di simile).

const food = { beef: '🥩', bacon: '🥓' };const cloneFood = { ...food };console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }

# 2. Utilizzando Oggetto.assegna

In alternativa,Object.assign è nel rilascio ufficiale e creerà anche una copia superficiale dell’oggetto.,

const food = { beef: '🥩', bacon: '🥓' };const cloneFood = Object.assign({}, food);console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }

Nota il vuoto {} come primo argomento, questo ti assicurerà di non mutare l’oggetto originale

# 3. Usando JSON

Questo modo finale ti darà una copia profonda. Ora dirò, questo è un modo rapido e sporco di clonazione profonda di un oggetto. Per una soluzione più robusta, consiglierei di usare qualcosa come lodash

const food = { beef: '🥩', bacon: '🥓' };const cloneFood = JSON.parse(JSON.stringify(food));console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }

# Lodash DeepClone vs JSON

Ecco un commento dalla comunità. Sì, è stato per il mio post precedente, Come clonare in profondità un array ., Ma l’idea si applica ancora agli oggetti.

Alfredo Salzillo: Mi piacerebbe che tu notassi che ci sono alcune differenze tra deepClone e JSON.stringify / analisi.per saperne di piùstringify / parse funziona solo con Numero e Stringa e Oggetto letterale senza proprietà funzione o simbolo.

  • deepClone lavorare con tutti i tipi, funzione e simbolo vengono copiati per riferimento.
  • Ecco un esempio:

    @OlegVaraksin : Il metodo JSON ha problemi con dipendenze circolari. Inoltre, l’ordine delle proprietà nell’oggetto clonato potrebbe essere diverso.,

    # Shallow Clone vs Deep Clone

    Quando ho usato spread... per copiare un oggetto, sto solo creando una copia superficiale. Se l’array è nidificato o multidimensionale, non funzionerà. Ecco il nostro esempio useremo:

    const nestedObject = { flag: '🇨🇦', country: { city: 'vancouver', },};

    # Copia Superficiale

    clonare il nostro oggetto mediante diffusione:

    const shallowClone = { ...nestedObject };// Changed our cloned objectshallowClone.flag = '🇹🇼';shallowClone.country.city = 'taipei';

    Così abbiamo cambiato il nostro oggetto clonato cambiando la città. Vediamo l’uscita.

    console.log(shallowClone);// {country: '🇹🇼', {city: 'taipei'}}console.log(nestedObject);// {country: '🇨🇦', {city: 'taipei'}} <-- 😱

    Una copia superficiale significa che il primo livello viene copiato, i livelli più profondi sono referenziati.,

    # Deep Copy

    Prendiamo lo stesso esempio ma applicando una copia profonda usando “JSON”

    Come puoi vedere, la copia profonda è una copia true per gli oggetti nidificati. Spesso la copia superficiale del tempo è abbastanza buona, non hai davvero bisogno di una copia profonda. E ‘ come una pistola sparachiodi contro un martello. Il più delle volte il martello è perfettamente a posto. Utilizzando una pistola sparachiodi per alcune piccole arti e artigianato è spesso caso di un eccessivo, un martello è bene. Si tratta di utilizzare lo strumento giusto per il lavoro giusto

    # Performance

    Sfortunatamente, non posso scrivere un test per lo spread perché non è ancora ufficialmente nelle specifiche., Tuttavia, l’ho incluso nel test in modo da poterlo eseguire in futuro 😝. Ma il risultato mostra Object.assign è molto più veloce di JSON.

    Test delle prestazioni

    # Ingresso comunità

    # Oggetto.assegna vs Spread

    @d9el : è importante notare quell’Oggetto.assign è una funzione che modifica e restituisce l’oggetto di destinazione. Nell’esempio di Samantha usando quanto segue,

    const cloneFood = Object.assign({}, food);

    {} è l’oggetto che viene modificato., L’oggetto di destinazione non è referenziato da alcuna variabile a quel punto, ma poichéObject.assign restituisce l’oggetto di destinazione, siamo in grado di memorizzare l’oggetto assegnato risultante nella variabilecloneFood. Potremmo cambiare il nostro esempio e usare quanto segue:

    const food = { beef: '🌽', bacon: '🥓' };Object.assign(food, { beef: '🥩' });console.log(food);// { beef: '🥩', bacon: '🥓' }

    Ovviamente, il valore di beef nel nostro oggetto food è sbagliato, quindi possiamo assegnare il valore corretto di beef usando Object.assign., In realtà non stiamo affatto utilizzando il valore restituito della funzione, ma stiamo modificando il nostro oggetto di destinazione a cui abbiamo fatto riferimento con const food.

    Spread d’altra parte è un operatore che copia le proprietà di un oggetto in un nuovo oggetto., Se abbiamo voluto replicare l’esempio di cui sopra mediante la diffusione di modificare la nostra variabile food...

    const food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};// TypeError: invalid assignment to const `food'

    ... si ottiene un errore, perché l’uso di diffusione durante la creazione di nuovi oggetti, e pertanto l’assegnazione di un nuovo oggetto food che è stato dichiarato con const, che è illegale., Così si può scegliere di dichiarare una nuova variabile per contenere il nostro nuovo oggetto, come la seguente:

    const food = { beef: '🌽', bacon: '🥓' };const newFood = { ...food, beef: '🥩',};console.log(newFood);// { beef: '🥩', bacon: '🥓' }

    o possiamo dichiarare food con let o var che ci permetterà di assegnare un nuovo oggetto:

    let food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};console.log(food);// { beef: '🥩', bacon: '🥓' }

    Grazie: @d9el

    # Profondo Clone uso di Librerie Esterne

    # Più Modi, utilizzando JavaScript

    • @hariharan_d3v : Object.fromEntries(Object.entries(food)) cloni oggetto.

    Lascia un commento

    Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *