Introduzione
Quando si parla di ES6+, si intende l’insieme delle versioni moderne di JavaScript introdotte a partire da ECMAScript 2015 e arricchite negli anni successivi. Tra le novità più utili per chi sviluppa applicazioni reali ci sono i miglioramenti nella gestione delle variabili, in particolare let e const, che hanno cambiato il modo di scrivere codice più sicuro, leggibile e meno soggetto a errori.
Prima di ES6, in JavaScript si usava quasi sempre var. Questo creava spesso confusione perché var ha uno scope di funzione e non di blocco, inoltre può essere ridefinita e “alzata” in modo poco intuitivo. Con let e const il linguaggio diventa più prevedibile: puoi dichiarare variabili con uno scope più chiaro e ridurre i bug legati a riassegnazioni accidentali.
In questo tutorial vedremo un sotto-argomento molto pratico e fondamentale per ES6+: la differenza tra let, const e var, con un focus sullo scope e sulle buone pratiche di utilizzo. È un tema essenziale perché influenza tutto il resto del codice moderno: funzioni, cicli, condizioni, moduli e gestione dello stato.
Codice completo
// Esempio completo: confronto tra var, let e const
function esempioScope() {
if (true) {
var messaggioVar = "Visibile fuori dal blocco";
let messaggioLet = "Visibile solo nel blocco";
const messaggioConst = "Anch´essa visibile solo nel blocco";
console.log("Dentro il blocco:");
console.log(messaggioVar);
console.log(messaggioLet);
console.log(messaggioConst);
}
console.log("Fuori dal blocco:");
console.log(messaggioVar); // Funziona: var è function-scoped
// Le righe seguenti genererebbero un errore:
// console.log(messaggioLet);
// console.log(messaggioConst);
}
esempioScope();
console.log("-----");
// Esempio di riassegnazione e mutabilità
let punteggio = 10;
punteggio = 15; // OK: let consente la riassegnazione
console.log("Punteggio aggiornato:", punteggio);
const utente = {
nome: "Luca",
ruolo: "editor"
};
// const impedisce la riassegnazione della variabile
// utente = { nome: "Marco" }; // Errore
// Ma l´oggetto interno può essere modificato
utente.ruolo = "admin";
console.log("Utente aggiornato:", utente);
console.log("-----");
// Esempio pratico: ciclo con let
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log("Indice corretto:", i);
}, 100);
}
// Esempio con var che può creare problemi
for (var j = 0; j < 3; j++) {
setTimeout(() => {
console.log("Indice con var:", j);
}, 100);
}
// Esempio di costante per configurazione
const API_URL = "https://api.example.com/v1";
const TIMEOUT_MS = 5000;
console.log("API_URL:", API_URL);
console.log("TIMEOUT_MS:", TIMEOUT_MS); Spiegazione
Il punto chiave di ES6 in questo argomento è lo scope, cioè il contesto in cui una variabile è accessibile.
1. var: scope di funzione
var è il vecchio modo di dichiarare variabili. Il suo comportamento può essere fonte di confusione perché non rispetta lo scope di blocco. Questo significa che se dichiari una variabile dentro un if o un for, spesso la variabile resta visibile anche fuori dal blocco.
Nel codice di esempio, messaggioVar è accessibile anche dopo il blocco if. Questo può sembrare comodo, ma in pratica aumenta il rischio di collisioni, sovrascritture accidentali e bug difficili da tracciare.
2. let: scope di blocco e riassegnazione consentita
let introduce uno scope di blocco. La variabile esiste solo all’interno delle parentesi graffe in cui è stata dichiarata. Questo comportamento è molto più intuitivo e sicuro.
Inoltre, let permette la riassegnazione. È perfetto per valori che cambiano nel tempo, come contatori, stato temporaneo, risultati intermedi di un calcolo o variabili aggiornate da un input utente.
Nel ciclo for dell’esempio, usare let è fondamentale: ogni iterazione mantiene il valore corretto di i. Quando si usano callback asincrone, come setTimeout, questo evita un comportamento inatteso molto comune con var.
3. const: scope di blocco e valore non riassegnabile
const ha lo stesso scope di let, ma non consente la riassegnazione della variabile. Questo lo rende ideale per valori che non dovrebbero cambiare, come configurazioni, riferimenti a servizi, funzioni, oggetti di appoggio o array che non devono essere rimpiazzati.
Attenzione però a un errore frequente: const non rende immutabile il contenuto di un oggetto o di un array. Significa solo che il riferimento non può essere assegnato a un nuovo valore. Nel caso dell’oggetto utente, non possiamo fare utente = ..., ma possiamo modificare una proprietà come utente.ruolo.
4. Hoisting: perché var può sorprendere
Un altro aspetto importante è l’hoisting, cioè il comportamento con cui JavaScript “sposta” le dichiarazioni in fase di interpretazione. Con var, la variabile viene sollevata ma inizializzata con undefined, quindi può essere letta prima della dichiarazione senza errore immediato. Questo spesso nasconde problemi.
Con let e const, invece, esiste la temporal dead zone: la variabile non è accessibile prima della dichiarazione. Questo è un vantaggio, perché il codice fallisce subito quando c’è un uso scorretto, rendendo i bug più facili da individuare.
5. Perché questo tema è centrale in ES6+
Molte altre novità di ES6+ funzionano meglio se si parte da una gestione corretta delle variabili. Per esempio:
- nei cicli con let si gestiscono correttamente gli indici;
- con const si definiscono costanti di configurazione chiare;
- nei moduli moderni si preferisce esportare valori che non cambiano;
- nelle funzioni asincrone si riduce il rischio di usare valori modificati in modo inatteso.
Best practice
- Usa const come scelta predefinita quando la variabile non deve essere riassegnata.
- Usa let solo quando sai che il valore cambierà, ad esempio in contatori, accumuli o stato temporaneo.
- Evita var nel codice moderno, salvo casi di manutenzione su codice legacy.
- Non confondere const con immutabilità: un oggetto dichiarato con const può comunque avere proprietà modificabili.
- Dichiara le variabili nel punto più vicino possibile all’uso, così il codice resta più leggibile.
- Usa nomi chiari e descrittivi, specialmente per costanti di configurazione come URL, timeout, limiti e flag.
- Evita di riutilizzare la stessa variabile per scopi troppo diversi: crea variabili separate se il significato cambia.
Una buona regola pratica è questa: prima const, poi let, mai var. È una sintesi semplice ma molto efficace per scrivere JavaScript moderno in modo pulito.
Riepilogo
In ES6+ la gestione delle variabili è diventata molto più solida grazie a let e const. Rispetto a var, queste dichiarazioni introducono uno scope di blocco, rendono il comportamento più prevedibile e aiutano a scrivere codice meno fragile.
Ricorda i punti fondamentali:
- var ha scope di funzione e può creare comportamenti inattesi;
- let serve per variabili che cambiano valore;
- const serve per riferimenti che non devono essere riassegnati;
- gli oggetti e gli array dichiarati con const possono comunque essere modificati internamente;
- lo scope di blocco è una delle basi del JavaScript moderno.
Se vuoi padroneggiare davvero ES6+, partire bene da let e const è una scelta strategica: migliora la qualità del codice e rende più semplice comprendere le altre novità del linguaggio.
Approfondisci con risorse ufficiali
- MDN Web Docs - let: documentazione completa e aggiornata sul comportamento di let.
- MDN Web Docs - const: guida ufficiale su costanti e scope di blocco.
- MDN Web Docs - var: utile per confrontare il comportamento storico di JavaScript.
- ECMAScript Specification: specifica ufficiale del linguaggio per approfondire i dettagli tecnici.
- JavaScript Guide di MDN: ottima risorsa per collegare ES6+ alle pratiche di sviluppo moderne.
