Sébastien TIMONER
Esperto in sviluppo web e gestione di team tecnici, mi specializzo nella creazione e ottimizzazione di soluzioni digitali performanti. Grazie a una profonda padronanza di tecnologie moderne come React.js, Node.js, TypeScript, Symfony, Docker e FrankenPHP, garantisco il successo di progetti SaaS complessi, dalla progettazione alla messa in produzione, per aziende di diversi settori.
Ciao, sviluppatore JavaScript che ti strappi i capelli con queste variabili! Ti chiedi quando usare var, let o const senza fare figure barbine nelle riunioni di team? Resta con me, lo risolveremo insieme, con calma e un sorriso. Nel programma: esploreremo ogni parola chiave, confronteremo i loro scope (globale, funzione, blocco), rideremo un po' dell'hoisting (quel meccanismo un po' magico di JavaScript), includeremo esempi pratici e finiremo con un tocco di TypeScript. Pronto? Andiamo!
Iniziamo con var, il più anziano delle variabili JavaScript. Se JavaScript fosse una serie TV, var sarebbe quel personaggio old-school, imprevedibile ma affascinante. Fino a ES5, era tutto ciò che avevamo per dichiarare le nostre variabili. Puoi ancora usarlo oggi, ma attenzione: ha alcune peculiarità che potrebbero sorprenderti.
var x = 1; var x = 2;
non genererà un errore – JavaScript semplicemente sovrascriverà il primo valore con il secondo. Utile per il codice legacy, ma una fonte di confusione da evitare nel nuovo codice.Per illustrare lo scope eccessivamente ampio di var, ecco un piccolo esempio:
javascript
Sì, anche se questo fruit è stato dichiarato all'interno di un'istruzione if, il console.log fuori dal blocco lo mostra senza problemi. A var non importano i limiti del blocco: è globale o legato alla sua funzione contenitore, punto.
E il meglio (o il peggio) per ultimo: l'hoisting. In italiano a volte lo chiamiamo "sollevamento", ma siamo onesti, usiamo principalmente il termine hoisting. È la tendenza di var a dichiararsi silenziosamente all'inizio dello scope. JavaScript, durante l'esecuzione, si comporta come se tutte le dichiarazioni var fossero state "sollevate" all'inizio della funzione. Di conseguenza, puoi usare la tua variabile prima della sua linea di dichiarazione... con un valore predefinito un po' strano. Vediamo questo più da vicino nella sezione hoisting più avanti (spoiler: var adora sorprenderti con undefined).
In sintesi, var ci ha servito bene, ma è un po' subdolo ai bordi: scope ampio, rideclarazione silenziosa, hoisting imprevedibile... Possiamo fare meglio, e fortunatamente, ES6 ha introdotto nuove parole chiave per mettere ordine nel caos.
Nel 2015, JavaScript ha accolto let (insieme a const). E lì, abbiamo ottenuto un piccolo restyling delle variabili. let è come il ragazzo figo e disciplinato: corregge la maggior parte delle peculiarità di var mantenendosi flessibile.
let x = 1; let x = 2;
nello stesso blocco, otterrai un bel SyntaxError: Identifier 'x' has already been declared
. Questo evita molta confusione, ammettilo.Per vedere chiaramente la differenza di scope con var, confrontiamo con l'esempio precedente sostituendo var con let:
javascript
Con let, una volta usciti dalle parentesi graffe dell'istruzione if, è fatta, la variabile vegetable non è più definita. Prova a registrarla e bam: ReferenceError. Questo è let che fa rispettare un buon comportamento di scope.
E l'hoisting? Le variabili let (e const) vengono anche sollevate, ma in modo diverso. Non sono utilizzabili prima di essere dichiarate. Tecnicamente, il motore JS sa che esistono nel blocco (riserva la memoria), ma finché non viene eseguita la linea di dichiarazione, qualsiasi tentativo di accesso genererà un errore. Diciamo che queste variabili sono nella Zona Morta Temporale (sì, suona come un film horror, ma è solo il nome elegante per "inaccessibile prima dell'inizializzazione"). Dettaglieremo questo comportamento più avanti, ma ricorda che let non ti lascerà usare una variabile troppo presto.
Nella pratica, let è diventata l'opzione predefinita per le variabili che cambieranno nel tempo. Porta chiarezza (scope di blocco) e sicurezza (nessuna rideclarazione accidentale, nessun accesso prima della dichiarazione). In breve, let è il tuo nuovo amico per dichiarare variabili temporanee o modificabili.
Ora a const! Introdotto contemporaneamente a let, questa parola chiave crea costanti... o quasi. Diciamo che crea variabili la cui riferimento non cambierà. const ha lo stesso scope di blocco di let (non più var che vagano) e le stesse regole di hoisting (zona morta temporale fino alla dichiarazione). La grande differenza è che una volta inizializzata, la variabile non può essere riassegnata.
const x;
da solo non funzionerà (SyntaxError diretto). Devi fare const x = 42;
per esempio.Guarda questo piccolo esempio per vedere chiaramente la differenza con una variabile modificabile:
javascript
Definiamo PI come costante, possiamo usarlo senza preoccupazioni finché non proviamo a cambiarlo. Quando proviamo a fare PI = 3.15, JavaScript ci ferma di colpo: non modificare una costante.
Nota: Costante non significa 100% immutabile. Se il valore è un oggetto o un array, puoi ancora modificare l'interno dell'oggetto/array. Quello che non si muove è la variabile stessa (il riferimento in memoria). Per esempio:
javascript
Qui, abbiamo potuto cambiare name nell'oggetto user nonostante const. Tuttavia, riassegnare completamente user a un altro oggetto è proibito. Quindi, const = costante, non modificabile, ma solo a livello della variabile stessa. Non confondere costanza di variabile con immutabilità di valore.
javascript
Con un array, è la stessa logica: possiamo modificare il suo contenuto (aggiungere, eliminare, modificare elementi) perché stiamo solo cambiando l'interno dell'array. Ma non possiamo riassegnare la variabile fruits a un nuovo array. È come se l'array fosse una scatola: possiamo cambiare quello che c'è dentro, ma non possiamo sostituire la scatola stessa.
Nella pratica, const è ideale per tutti i valori che non dovrebbero cambiare: per esempio una configurazione, un riferimento, ecc. È ampiamente usato e rende il codice più robusto (sappiamo che questa variabile non si muoverà). In effetti, le best practice spesso raccomandano di usare const di default, e passare a let solo quando sappiamo che il valore dovrà cambiare. Quanto a var... beh, a meno che non ci sia una ragione specifica, lo dimentichiamo 😉.
Parliamo di più di scope. Lo scope determina "dove" una variabile è accessibile nel tuo codice. Ci sono principalmente tre livelli di scope in JavaScript:
In sintesi: var è limitato alla funzione (o globale), mentre let e const sono limitati al blocco corrente. Questa differenza risolve molti problemi classici. Per esempio:
javascript
Qui, il ciclo con var lascia i appeso fuori, con il suo valore finale 3. Il ciclo con let, d'altra parte, pulisce j all'uscita: impossibile accedervi dopo. Nella pratica, questo significa che puoi avere diverse variabili let con lo stesso nome in blocchi diversi senza interferenza, dove un singolo var sarebbe stato condiviso tra tutti questi blocchi.
Passiamo all'hoisting, questo meccanismo di sollevamento delle dichiarazioni. Spesso è una fonte di confusione (e battute nelle riunioni), quindi chiariamolo. L'hoisting è quando il motore JavaScript "sposta" le dichiarazioni di variabili e funzioni all'inizio del loro scope durante l'esecuzione. In realtà, nulla si muove davvero nel tuo codice, è solo che JavaScript alloca memoria per le tue variabili in anticipo, prima di eseguire passo dopo passo.
Facciamo un piccolo test di hoisting nella pratica:
javascript
Al momento del primo console.log, la variabile myVar è stata effettivamente creata in memoria attraverso l'hoisting, ma il suo valore predefinito è undefined (poiché non l'abbiamo ancora assegnata). Nessun errore, viene mostrato solo undefined. Poi assegniamo "Ciao", e la seconda volta otteniamo il valore atteso.
Ora vediamo con let:
javascript
Qui, il primo console.log scatena un ReferenceError. Perché? Perché myLet viene sollevato senza inizializzazione. È nella sua zona morta temporale, inaccessibile. JavaScript si rifiuta di darci un valore che non esiste ancora realmente. Una volta che eseguiamo let myLet = "Ciao";
, la variabile esce dalla sua zona morta e ottiene "Ciao". Il secondo console.log funziona perfettamente.
Possiamo vederlo chiaramente: var si comporta come un ninja sollevando la sua dichiarazione e dandosi silenziosamente il valore undefined, mentre let/const giocano sul sicuro e prevengono qualsiasi uso finché non sono inizializzati. Morale della storia: evita di codificare affidandoti all'hoisting, è una ricetta per nodi cerebrali (e undefined inaspettati). Meglio dichiarare le tue variabili all'inizio dei loro scope e mantenere il tuo codice chiaro. Se lo dimentichi, il comportamento di let/const ti ricorderà con un errore, dove var ti avrebbe lasciato sguazzare con un undefined.
Ah, e mentre ci siamo, nota che le funzioni dichiarate classicamente (function myFunction() \{ ... \}
) vengono anche sollevate completamente. Puoi chiamare una funzione dichiarata più in basso nel tuo codice, JavaScript la conoscerà già. Ma attenzione, le funzioni freccia o espressioni di funzione assegnate a variabili seguono le regole di hoisting di var/let secondo la parola chiave utilizzata (un argomento per un altro giorno 😉).
Prima di salutarci, parliamo brevemente di TypeScript. Se inizi a usare TypeScript (il super-set di JavaScript che aggiunge il tipaggio statico), troverai i nostri tre amici var, let e const. Buone notizie: i loro comportamenti di scope e hoisting rimangono esattamente gli stessi che in JavaScript puro, poiché TypeScript viene compilato in JavaScript standard. Tuttavia, TypeScript porta il suo tocco personale alla tipizzazione, e vale la pena darci un'occhiata, specialmente per let e const.
let fruit = "mela";
, TypeScript inferirà che fruit è di tipo string. Se scrivi let age = 25;
, capirà che age è un numero, ecc. Per let, rimane abbastanza ampio: la variabile può cambiare, quindi il tipo è quello base (string, number, ecc.).typescript
La variabile color è di tipo "rosso" e non solo string. Vantaggio? Se più tardi il tuo codice si aspetta esattamente il valore "rosso" o "blu" (per esempio un parametro che può essere solo uno di questi colori), e hai const color = "rosso"
, puoi passarlo senza preoccupazioni. Con un let color = "rosso"
(tipo string ampio), TypeScript si sarebbe lamentato perché "rosso" è solo una possibilità tra tutte le stringhe. In breve, const in TypeScript permette una tipizzazione ultra precisa quando è utile. È come un bonus che rafforza ulteriormente il concetto di costante.
console.log(myVar); var myVar = 3;
, segnalerà che hai un problema di scope o ordine. Lo stesso per un let usato troppo presto, TS conosce le regole di hoisting e ti proteggerà (per quanto possibile) dagli errori.In sintesi, TypeScript non cambia le regole fondamentali di var/let/const, ma le rafforza con la rete di sicurezza della tipizzazione. Guadagni in chiarezza e catturi gli errori prima. Ricorda specialmente che const in TypeScript è doppiamente vincente: una variabile non riassegnabile e un tipo letterale preciso – cosa potresti volere di più?
Abbiamo coperto tutto, quindi chi è il vincitore nella partita var vs let vs const? Nessuna sorpresa: nel 2025, il duo let & const vince a mani basse per scrivere codice pulito e manutenibile. Ecco un riassunto piccante di consigli pratici:
Ecco fatto, ora sai quando usare var, let o const in JavaScript, e anche un po' su come funziona con TypeScript. Non più confusione sui nostri tre compagni né prese in giro nella code review perché hai tirato fuori un var dal cappello senza una ragione valida. Vai a codificare pacificamente, e non dimenticare: const il più possibile, let se necessario, e var... il meno possibile! Happy coding!