Nella programmazione, la mutazione di un oggetto implica che lo stato o i dati di un oggetto vengano modificati dopo la creazione. In altre parole, l’operazione che cambia gli attributi di un oggetto in JavaScript è nota come mutazione dell’oggetto. La mutazione dell’oggetto altera direttamente i valori di un oggetto, rendendola impegnativa, specialmente nelle applicazioni in cui varie operazioni possono tentare di leggere o scrivere su un oggetto contemporaneamente.
Questo articolo presenta una discussione sulla mutazione dell’oggetto in JavaScript con esempi di codice pertinenti quando necessario.
Tipi di Dati in JavaScript
I tipi di dati indicano il tipo di dati che una variabile o un oggetto può contenere. JavaScript supporta due categorie distinte di tipi di dati: primitivi e definiti dall’utente o di riferimento.
Tipi di Dati Primitivi
In JavaScript, tutti i tipi di dati primitivi sono immutabili per natura, ovvero non è possibile modificarli dopo che sono stati creati. Numeri, Booleani, Stringhe, Bigint, Undefined, Null, Symbol e Oggetti sono esempi di tipi primitivi.
Tipi di Dati Definiti dall’Utente o di Riferimento
I tipi di dati definiti dall’utente o di riferimento sono oggetti creati utilizzando tipi primitivi o una combinazione di tipi primitivi e definiti dall’utente. Esempi tipici di tipi definiti dall’utente o di riferimento sono gli oggetti e gli array.
Come le Variabili Vengono Assegnate e Riasssegnate in JavaScript
Quando si assegna una variabile di tipo primitivo a una variabile di tipo primitivo, le due variabili contengono valori simili, ma sono memorizzate in posizioni di memoria diverse. Ad esempio, supponiamo di avere due variabili varA e varB e si assegna una variabile all’altra nel seguente modo:
var varA = 100;
var varB = varA;
console.log(varB);
Quando si esegue il precedente pezzo di codice, il numero 100 verrà visualizzato sulla console. Ora, si cambiano i valori di una delle due variabili (ad esempio varB) come mostrato qui.
var varA = 100;
var varB = varA;
varB = 500;
console.log(varA);
Nota come il valore della variabile varB è stato cambiato in 500. Quando si stampa il valore di varA, continuerà a visualizzare 100. Questo perché queste variabili varA e varB sono memorizzate in due posizioni di memoria diverse. Quindi, se si cambia una di esse, il nuovo valore o il valore cambiato non si rifletterà sulle altre variabili.
Cosa è la mutazione degli oggetti in JavaScript?
In JavaScript, il tipo di dati di un oggetto può appartenere a una delle due categorie: primitivo o non primitivo. Mentre i tipi primitivi sono immutabili, cioè non è possibile modificarli dopo averli creati, è possibile modificare i tipi non primitivi, ovvero gli oggetti e gli array. Gli oggetti permettono sempre di cambiare i loro valori. Pertanto, è possibile modificare lo stato dei campi per un tipo mutabile senza creare una nuova istanza.
Le mutazioni degli oggetti possono creare diversi problemi, come i seguenti:
- Gli oggetti mutati possono spesso portare a condizioni di gara a causa di problemi di concorrenza e di sicurezza dei thread.
- La mutazione può introdurre complessità nel codice sorgente a causa di problemi di prevedibilità e sicurezza del thread
- La mutazione può spesso causare bug difficili da identificare nel codice sorgente dell’applicazione
- La mutazione rende difficile il testing e il debug del codice perché diventa una sfida tracciare il codice che sfrutta la mutazione
Esempi di codice che dimostrano la mutazione degli oggetti
La mutazione degli oggetti può verificarsi in uno qualsiasi dei seguenti scenari:
- Aggiunta, modifica o rimozione di proprietà
- Utilizzo di metodi che possono manifestare mutazione
Quando si modificano le proprietà di un oggetto, direttamente o indirettamente, si sta essenzialmente mutando l’oggetto. Il seguente frammento di codice mostra come è possibile mutare un oggetto modificandone la proprietà
const author = { id: 1, name: "Joydip Kanjilal"};
author.id = 2; author.city = "Hyderabad, INDIA";
console.log(author);
Nel pezzo di codice precedente, creiamo un oggetto chiamato autore che contiene due proprietà, ovvero, id
e name
. Mentre la proprietà id
viene utilizzata per memorizzare l’id
del record dell’autore, la proprietà name
memorizza il nome dell’autore. Notare come mutiamo l’oggetto autore modificando il valore relativo alla proprietà id
. Successivamente, aggiungiamo una nuova proprietà, chiamata città, all’oggetto autore e assegnamo un valore alla proprietà
Quando si esegue il pezzo di codice precedente, le proprietà e i loro valori dell’oggetto autore verranno visualizzati come mostrato di seguito:
{ name: 'Joydip Kanjilal', city: 'Hyderabad, INDIA' }
Quando si passa un oggetto a una funzione o lo si assegna a una variabile in JavaScript, si sta essenzialmente passando il riferimento all’oggetto e non una copia di esso. Ciò implica che qualsiasi modifica apportata al nuovo oggetto creato passando un oggetto o assegnandolo alla variabile si applicherà a tutti i riferimenti dell’oggetto effettivo.
Considera il seguente pezzo di codice che mostra come è possibile creare un oggetto in JavaScript e quindi assegnarlo a una variabile.
const objA = { id: 1, name: 'Joydip Kanjilal',
city: 'Hyderabad, INDIA', pincode: 500089 }
const objB = objA;
objB.pincode = 500034;
console.log(objA);
Nel pezzo di codice precedente, l’oggetto objA
è assegnato a objB
, e il valore della proprietà pincode di objA
viene modificato, cioè, l’oggetto objA
viene mutato. Quando si esegue il programma, verranno visualizzati i seguenti dati.
{ id: 1, name: 'Joydip Kanjilal', city: 'Hyderabad, INDIA', pincode: 500034 }
Nota che il valore della proprietà pincode è stato modificato.
Prevenire la Mutazione degli Oggetti in JavaScript
In JavaScript, è possibile prevenire la mutazione in diversi modi, come ad esempio:
- Utilizzando la clonazione degli oggetti sfruttando il metodo
Object.assign()
o l’operatore spread (…) - Utilizzando il metodo
Object.seal()
per impedire l’aggiunta o la rimozione di proprietà di un oggetto - Utilizzando il metodo
Object.freeze()
per impedire l’aggiunta, la modifica o la rimozione di proprietà di un oggetto
Utilizzando la Clonazione
Fai riferimento al seguente pezzo di codice che mostra come è possibile clonare un oggetto in JavaScript utilizzando l’operatore spread.
let originalObj = { x: 10, y: 100 }; let clonedObj = { originalObj };
Qui, il nome dell’oggetto clonato è clonedObj
, ed è identico all’oggetto originale chiamato originalObj
. Quindi, se visualizzi i valori delle due proprietà di questi due oggetti, i risultati saranno gli stessi.
Ora, cambia il valore di una delle proprietà dell’oggetto clonato chiamato clonedObj
al valore desiderato, come mostrato nel pezzo di codice fornito di seguito.
clonedObj.x = 50;
Ora, scrivi il seguente pezzo di codice per visualizzare il valore della proprietà chiamata x
relativamente ai due oggetti originalObj
e clonedObj
.
console.log(originalObj.x);
console.log(clonedObj.x);
Quando esegui il programma, osserverai che il valore della proprietà x
nell’oggetto originale non è cambiato. I valori verranno visualizzati sulla console come mostrato di seguito:
10
50
Usando il Metodo Object.freeze()
Il metodo Object.freeze()
può rendere un oggetto immutabile impedendo qualsiasi modifica a una qualsiasi delle sue proprietà.
const author = { id: 1, name: "Joydip Kanjilal",
city: "Hyderabad", state: "Telengana",
country: "India", pincode: 500089};
Object.freeze(author);
author.city = "Bangalore";
author.state = "Karnataka";
author.pincode = 560010;
console.log(author);
Quando esegui il pezzo di codice precedente, i risultati saranno simili a questo:
{
id: 1,
name: 'Joydip Kanjilal',
city: 'Hyderabad',
state: 'Telangana',
country: 'India',
pincode: 500089
}
Come puoi vedere dall’output, anche se hai assegnato valori alle proprietà city e state e pincode, non c’è alcun effetto. Quindi, nessuna modifica è stata apportata ai dati contenuti in nessuna delle proprietà dell’oggetto.
Usando il Metodo Object.seal()
Puoi anche utilizzare il metodo Object.seal()
per impedire la mutazione dell’oggetto in JavaScript. Questo metodo ti consentirebbe di modificare i valori delle proprietà esistenti, ma non puoi modificare o eliminare nessuna delle proprietà dell’oggetto. L’esempio di codice seguente illustra questo:
const author = { id: 1, name: "Joydip Kanjilal",
city: "Hyderabad", state: "Telangana",
country: "India", pincode: 500089};
Object.seal(author);
author.city = "Bangalore";
author.state = "Karnataka";
author.pincode = 560005;
author.booksauthored = 3;
console.log(author);
Nel frammento di codice precedente, mentre saranno consentite modifiche alle proprietà dell’oggetto chiamato autore, non sarà consentita né l’aggiunta né la rimozione delle proprietà dell’oggetto. Quando esegui il programma, vedrai che i valori delle proprietà modificate sono riflessi nel risultato, ma le istruzioni che aggiungono o eliminano proprietà vengono ignorate. Ecco come apparirebbe l’output sulla console:
{
id: 1,
name: 'Joydip Kanjilal',
city: 'Bangalore',
state: 'Karnataka',
country: 'India',
pincode: 560005
}
Utilizzo del metodo Object.defineProperty()
Puoi anche sfruttare il metodo Object.defineProperty()
in JavaScript per controllare la mutabilità delle singole proprietà di un oggetto. Il seguente frammento di codice mostra come puoi utilizzare questo metodo per impedire modifiche al valore contenuto in una proprietà il cui mutamento è limitato.
const author = { id: 1, name: "Joydip Kanjilal"};
Object.defineProperty(author, "booksauthored",
{
value: 3,
writable: false,
});
author.booksauthored = 5;
console.log(author.booksauthored);
Quando esegui il frammento di codice precedente, vedrai che il numero 3 viene visualizzato sulla console.
Punti chiave
- In JavaScript, i tipi di oggetti sono categorizzati in due categorie distinte: primitivi (mutabili) e oggetti (immobili).
- Il termine mutazione dell’oggetto si riferisce alle operazioni che modificano o cambiano un oggetto dopo che è stato creato.
- Mentre i valori primitivi come i numeri, ecc., non possono essere modificati, è sempre possibile modificare gli oggetti una volta creati.
- Dato che le stringhe in JavaScript sono immutabili, non è possibile modificarle una volta create.
- Anche se la mutazione di per sé non è così negativa, è importante gestirla attentamente per ridurre i bug nelle tue applicazioni.
- Puoi ridurre o eliminare la mutazione in JavaScript seguendo le pratiche consigliate e sfruttando le strutture dati immutabili.
Source:
https://dzone.com/articles/an-introduction-to-object-mutation-in-javascript