Clona in profondità un oggetto in JavaScript

Harshit Jindal 12 ottobre 2023
  1. Copia superficiale e copia profonda
  2. Metodi di copia superficiale in JavaScript
  3. Metodi di copia profonda in JavaScript
Clona in profondità un oggetto in JavaScript

JavaScript è un linguaggio di oggetti. Quasi tutto è un oggetto in JavaScript. Booleani, numeri, stringhe, date, matematica, espressioni regolari, matrici, funzioni e oggetti stessi, sono tutti oggetti. Sono una raccolta di coppie chiave-valore costituita da vari attributi e metodi. Vengono salvati direttamente in memoria e possono essere copiati solo per riferimento. Una variabile non memorizza l’oggetto ma solo un riferimento a quell’oggetto in memoria. Quindi, quando proviamo a copiare una variabile oggetto, finiamo per creare un riferimento extra allo stesso oggetto. Questo metodo è chiamato copia superficiale. Non è l’ideale in quanto non vogliamo che il cambiamento nell’oggetto originale influenzi il suo clone. Ciò crea la necessità di un metodo per clonare in profondità l’oggetto. Questo tutorial insegna come clonare in profondità un oggetto in JavaScript.

Copia superficiale e copia profonda

Una copia superficiale è una copia bit per bit dell’oggetto. Il nuovo oggetto creato copia con successo le primitive come numeri, booleani e stringhe ma non copia alcun riferimento agli oggetti. Solo gli indirizzi di riferimento danno come risultato un puntatore che punta allo stesso oggetto. Eventuali modifiche apportate all’oggetto originale si riflettono nella copia superficiale.

D’altra parte, una copia completa non copia solo l’indirizzo/riferimento all’oggetto originale ma l’intero oggetto. Il nuovo oggetto creato non ha alcuna dipendenza dall’oggetto copiato. JavaScript ci fornisce vari metodi integrati per copiare un oggetto, ma la copia superficiale è il comportamento predefinito nella maggior parte di essi.

Metodi di copia superficiale in JavaScript

Tratteremo brevemente i metodi di copia superficiale per farti conoscere alcuni dei modi sbagliati per eseguire la copia profonda.

Utilizzare la sintassi di diffusione per clonare in modo superficiale un oggetto in JavaScript

Possiamo clonare un oggetto creando un nuovo oggetto e quindi utilizzando la sintassi spread per enumerare il contenuto di un oggetto al suo interno come proprio. Sembra il modo giusto, ma crea una copia superficiale dei dati.

const obj = {
  a: 1,
  b: {c: 2}
}

const clone = {...obj};  // creates a shallow copy

obj.b.c = 5;
console.log(clone.b.c);  // outputs 5

Nel codice precedente, usiamo la sintassi spread per creare una copia superficiale dell’oggetto. Quindi modifichiamo una delle proprietà dell’oggetto di riferimento nell’oggetto originale e mostriamo che la proprietà è modificata nell’oggetto clonato.

Utilizzare Object.assign() per clonare in modo superficiale un oggetto in JavaScript

Il metodo object.assign() assegna una copia superficiale dell’oggetto a una nuova variabile oggetto. Richiede due argomenti: destinazione e origine. Il bersaglio è solitamente una coppia di parentesi vuote usate per rappresentare l’oggetto vuoto in cui copiare; è un argomento opzionale ma passarlo assicura che non si finisca per cambiare l’oggetto originale. Il secondo argomento è l’oggetto da copiare.

const obj = {
  a: 1,
  b: {c: 2}
}

const clone = Object.assign({}, obj);  // creates a shallow copy

obj.b.c = 5;
console.log(clone.b.c);  // outputs 5

Nel codice sopra, usiamo Object.assign() per creare una copia superficiale dell’oggetto. Quindi modifichiamo una delle proprietà dell’oggetto di riferimento nell’oggetto originale e mostriamo che la proprietà è modificata nell’oggetto clonato.

Metodi di copia profonda in JavaScript

Usa JSON.parse() e JSON.stringify() per clonare in profondità un oggetto in JavaScript

JSON.stringify() è usato per convertire un oggetto JavaScript in una stringa JSON e JSON.parse() è usato per convertire una stringa JSON in un oggetto JavaScript. Possiamo avvolgere JSON.parse() intorno a JSON.stringify() per convertire prima l’oggetto JavaScript in una stringa JSON e poi analizzarlo per ottenere una copia dell’oggetto.

var user = {name: 'Harshit', age: 21, Profession: 'Software Engineer'};
let fakeDeepCopy = JSON.parse(JSON.stringify(user));

Questo metodo crea una copia completa ma solo per gli oggetti senza funzioni. Ha problemi con le dipendenze circolari come altri oggetti referenziati. Anche l’ordine delle proprietà nell’oggetto copiato può differire dall’oggetto originale. Quindi, questo metodo è un bel trucco se abbiamo un oggetto semplice con pochi tipi di dati primitivi, ma non è raccomandato per il mondo reale.

Usa la clonazione profonda nativa per clonare in profondità un oggetto in JavaScript

Possiamo usare l’algoritmo di serializzazione del modulo Node.js v8 per clonare in profondità un oggetto. Sebbene sia limitato a determinati tipi di dati incorporati, conserva i riferimenti all’interno dei dati clonati. Ci permette di copiare diverse strutture cicliche e ricorsive che non erano supportate dal metodo JSON.

const v8 = require('v8');

const structuredClone = obj => {
  return v8.deserialize(v8.serialize(obj));
};

Deserializziamo e quindi serializziamo l’oggetto proprio come la stringa e l’analisi dei metodi JSON. Ma conserva le dipendenze circolari ed è leggermente migliore.

Usa la libreria Lodash per clonare in profondità un oggetto in JavaScript

La libreria Lodash ha funzioni sia per la copia superficiale che per quella profonda, vale a dire clone e clonedeep. È un’ottima libreria che ci permette di importare solo le funzioni di cui abbiamo bisogno e non la libreria completa. Il metodo clonedeep funziona copiando ricorsivamente il valore e quindi preservando tutte le eredità dell’oggetto, creando una copia fedele dell’oggetto.

const lodashClonedeep = require('lodash.clonedeep');
let obj = {a: 1, b: {c: 2}} let deepClone = lodashClonedeep(obj);

Qui carichiamo la funzione clonedeep da lodash e la usiamo per clonare in profondità l’oggetto. È una libreria ben testata e mantenuta, ma può essere utilizzata solo con Node.js e non con Vanilla JavaScript.

Usa il metodo jQuery extend() per clonare in profondità un oggetto in JavaScript

Possiamo usare .extend() di jQuery per eseguire la copia superficiale e la copia completa di un oggetto. È il metodo di clonazione profonda più affidabile senza perdita di dati o danneggiamento dei dati. La sua funzione principale è unire due o più oggetti. Ma può essere utilizzato anche per clonare un oggetto. Accetta i seguenti argomenti: [deep], target, object1 ..... objectN.

  1. [deep]: è un argomento opzionale. Il suo unico valore consentito è vero. Se viene passato alla funzione, la funzione crea una copia completa dell’oggetto. Altrimenti, forma una copia superficiale.
  2. target: l’oggetto da estendere. Riceverà tutti gli oggetti uniti.
  3. oggetto1, ..., oggettoN: questi sono gli oggetti da fondere/clonare in un nuovo oggetto.
let obj = {a: 1, b: {c: 2}} let shallowClone =
    $.extend({}, obj);                    // creates a shallow copy
let deepClone = $.extend(true, {}, obj);  // creates a deep copy

Una soluzione più ovvia può essere semplicemente iterare attraverso ogni proprietà dell’oggetto sorgente e replicarle in un nuovo oggetto. Tutti i metodi discussi sopra sono compatibili con tutti i principali browser.

Harshit Jindal avatar Harshit Jindal avatar

Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.

LinkedIn

Articolo correlato - JavaScript Object