Introduzione
Quando si studiano le variabili in JavaScript, è facile concentrarsi solo su let, const e sui tipi primitivi più noti come stringhe, numeri e booleani. Ma c’è un aspetto pratico che fa davvero la differenza nei progetti reali: come vengono assegnati, copiati e modificati i valori primitivi.
I tipi primitivi in JavaScript hanno una caratteristica importante: sono immutabili. Questo significa che, una volta creato un valore primitivo, non lo modifichi “in place”, ma ne ottieni uno nuovo. Capire bene questo comportamento aiuta a evitare bug comuni, soprattutto quando si lavora con variabili che vengono riassegnate, copiate o passate a funzioni.
In questo tutorial vedremo un sotto-argomento pratico e molto utile: la differenza tra assegnazione per valore dei primitivi e il comportamento delle variabili quando cambiano contenuto. È un concetto fondamentale per scrivere codice più prevedibile e più facile da mantenere.
Codice completo
// Esempio 1: assegnazione di un tipo primitivo
let username = "mario";
let altroUsername = username;
console.log(username); // "mario"
console.log(altroUsername); // "mario"
// Modifichiamo la seconda variabile
altroUsername = "luigi";
console.log(username); // "mario"
console.log(altroUsername); // "luigi"
// Esempio 2: numero primitivo
let punti = 10;
let copiaPunti = punti;
copiaPunti = copiaPunti + 5;
console.log(punti); // 10
console.log(copiaPunti); // 15
// Esempio 3: funzione che riceve un primitivo
function incrementaEta(eta) {
eta = eta + 1;
return eta;
}
let etaUtente = 29;
let nuovaEta = incrementaEta(etaUtente);
console.log(etaUtente); // 29
console.log(nuovaEta); // 30
// Esempio 4: uso di const con un primitivo
const paese = "Italia";
// paese = "Francia"; // Errore: non puoi riassegnare una const
// Esempio 5: costruzione di un nuovo valore
let prezzo = 100;
prezzo = prezzo * 0.9; // sconto del 10%
console.log(prezzo); // 90
// Esempio 6: controllo del tipo primitivo
let valore = "42";
console.log(typeof valore); // "string"
valore = 42;
console.log(typeof valore); // "number" Spiegazione
In JavaScript, i tipi primitivi includono valori semplici come string, number, boolean, null, undefined, symbol e bigint. Il punto chiave è che questi valori non sono oggetti e non hanno proprietà modificabili come gli oggetti o gli array.
1. L’assegnazione copia il valore
Quando fai:
let a = "ciao";
let b = a; stai copiando il valore contenuto in a dentro b. Dopo la copia, le due variabili sono indipendenti. Se cambi b, a resta invariata.
Questo comportamento è molto utile perché rende il codice più prevedibile. Se una variabile contiene un numero o una stringa, puoi riassegnarla senza temere effetti collaterali su altre variabili che avevano ricevuto lo stesso valore in precedenza.
2. I primitivi sono immutabili
Una stringa, per esempio, non viene modificata “pezzo per pezzo”. Se vuoi trasformarla, JavaScript crea un nuovo valore. Ecco un esempio:
let nome = "anna";
nome = nome.toUpperCase();
console.log(nome); // "ANNA" Qui non stai cambiando la stringa originale in modo interno: stai assegnando alla variabile nome una nuova stringa prodotta da toUpperCase().
3. let e const non cambiano la natura del primitivo
La parola chiave let ti permette di riassegnare la variabile. La parola chiave const, invece, blocca la riassegnazione del riferimento della variabile.
Con un primitivo, const significa che non puoi assegnare un nuovo valore alla variabile:
const anno = 2024;
// anno = 2025; // non valido Questo non vuol dire che il valore “si blocca” in senso assoluto, ma che la variabile non può essere ricollegata a un altro valore. Per i primitivi, è un comportamento semplice e molto sicuro.
4. Passaggio a funzione: il valore non viene condiviso
Quando passi un primitivo a una funzione, JavaScript passa una copia del valore. Per questo, se modifichi il parametro interno alla funzione, la variabile esterna non cambia.
Nel codice:
function incrementaEta(eta) {
eta = eta + 1;
return eta;
} eta è una variabile locale della funzione. Anche se parte dal valore di etaUtente, la modifica avviene solo dentro la funzione. Questo riduce gli effetti collaterali e rende il comportamento più chiaro.
5. Riassegnazione come strategia di lavoro
Molti programmatori intermedi commettono un errore: pensano che per “modificare” un primitivo debbano intervenire sul valore originale. In realtà, la strategia corretta è quasi sempre creare un nuovo valore e riassegnarlo.
Per esempio, se vuoi applicare uno sconto a un prezzo:
let prezzo = 100;
prezzo = prezzo * 0.9; Non stai alterando il numero 100: stai calcolando un nuovo valore e assegnandolo a prezzo.
Best practice
- Usa const di default quando la variabile non deve essere riassegnata. È una scelta che riduce gli errori e rende il codice più leggibile.
- Usa let solo quando serve davvero la riassegnazione, ad esempio in cicli, contatori o trasformazioni progressive.
- Tratta i primitivi come valori indipendenti: se li copi, ottieni una nuova variabile con lo stesso contenuto iniziale.
- Non aspettarti mutazioni interne su stringhe, numeri o booleani. Per cambiarli, crea un nuovo valore.
- Controlla il tipo con typeof quando ricevi dati da input, API o form: spesso un numero arriva come stringa.
- Scrivi funzioni pure quando possibile: se una funzione riceve primitivi e restituisce un nuovo valore, il comportamento è più facile da testare.
Riepilogo
Il concetto più importante da portare a casa è questo: i tipi primitivi in JavaScript vengono gestiti come valori semplici e indipendenti. Quando assegni un primitivo a un’altra variabile, copi il valore. Quando lo passi a una funzione, la funzione lavora su una copia locale. Quando vuoi “modificarlo”, in realtà crei un nuovo valore e lo riassegni.
Questo comportamento è una base fondamentale per capire meglio le variabili in JavaScript e per evitare confusione quando si passa da esempi semplici a codice più complesso. Se impari bene il rapporto tra variabili, assegnazione e immutabilità dei primitivi, scriverai codice più pulito, affidabile e facile da debuggare.
Approfondisci con risorse ufficiali
- MDN Web Docs - JavaScript data types and data structures: documentazione completa sui tipi di dati.
- MDN Web Docs - let: comportamento delle variabili dichiarate con let.
- MDN Web Docs - const: regole di riassegnazione e utilizzo corretto.
- MDN Web Docs - typeof: operatore utile per riconoscere il tipo di un valore.
- ECMAScript Language Specification: riferimento ufficiale per chi vuole approfondire il comportamento del linguaggio.
