W3docs

Scope delle Variabili in JavaScript

Comprendere lo scope delle variabili in JavaScript è essenziale per ogni sviluppatore. Questa guida illustra i tipi di scope, le funzioni annidate e le differenze tra var, let e const.

Scope è la parte di un programma in cui una variabile è visibile e può essere utilizzata. Comprendere lo scope ti permette di prevedere a quale valore fa riferimento un nome, evitare collisioni accidentali tra variabili e capire perché una variabile è o non è disponibile in un determinato punto. Questa guida spiega i tipi di scope in JavaScript, come le funzioni annidate accedono agli scope circostanti, in cosa differisce var da let/const, e come tutto questo porta naturalmente alle closure.

I tre tipi di scope

JavaScript determina la visibilità delle variabili in base a dove la variabile è dichiarata nel codice sorgente — questo si chiama scope lessicale (o statico). Esistono tre livelli:

  • Scope globale — dichiarato fuori da qualsiasi funzione o blocco. Visibile ovunque.
  • Scope di funzione — dichiarato all'interno di una funzione. Visibile solo all'interno di quella funzione (così funziona var).
  • Scope di blocco — dichiarato con let o const all'interno di un blocco { ... } (un if, un for, o anche un semplice {}). Visibile solo all'interno di quel blocco.

Scope globale

Una variabile dichiarata al livello superiore di uno script è globale: ogni funzione e blocco può leggerla e scriverla.

javascript— editable

Le variabili globali sono comode ma rischiose: qualsiasi parte del programma può modificarle, e due porzioni di codice non correlate possono scegliere lo stesso nome e sovrascriversi a vicenda. Mantieni ridotto il namespace globale.

Scope di funzione

Una variabile dichiarata all'interno di una funzione esiste solo mentre quella funzione è in esecuzione ed è invisibile dall'esterno.

javascript— editable

Il blocco try...catch consente all'esempio di continuare l'esecuzione in modo da poter vedere il messaggio di errore invece che lo script si interrompa semplicemente.

Scope di blocco

let e const hanno scope limitato al blocco racchiudente più vicino, non all'intera funzione. Una variabile dichiarata all'interno di un blocco if o for scompare una volta terminato il blocco.

javascript— editable

Come le funzioni annidate vedono le variabili esterne

Quando si annidano funzioni, la funzione interna può leggere le variabili da ogni scope che la circonda — il proprio, quello della funzione contenitore e lo scope globale. Questa catena di scope accessibili è chiamata ambiente lessicale (o catena di scope).

Quando JavaScript cerca un nome, inizia dallo scope corrente e risale verso l'esterno finché non trova la variabile. Se raggiunge lo scope globale senza trovarla, si ottiene un ReferenceError.

javascript— editable

La ricerca avviene solo verso l'esterno, mai verso l'interno — outer() non può vedere innerVar. Questo è esattamente il meccanismo che rende possibili le closure: una funzione interna mantiene l'accesso alle variabili esterne anche dopo che la funzione esterna ha terminato la sua esecuzione.

var vs let e const

Le regole di scope differiscono in base al modo in cui si dichiara una variabile. var ha scope di funzione e ignora i blocchi, mentre let e const hanno scope di blocco. Questa è una delle fonti più comuni di bug nel codice datato.

javascript— editable

La trappola classica è un ciclo che crea callback. Con var c'è una sola variabile condivisa; con let ogni iterazione ottiene il proprio binding:

javascript— editable

Per un'analisi più approfondita delle particolarità di var — incluso l'hoisting e la mancanza di scope di blocco — consulta il vecchio "var".

Hoisting e la Temporal Dead Zone

Le dichiarazioni vengono elaborate prima che il codice venga eseguito. Una dichiarazione var viene sollevata (hoisted) e inizializzata a undefined, quindi leggerla prima dell'assegnazione restituisce undefined invece di un errore. let e const vengono anch'essi sollevati, ma rimangono in una Temporal Dead Zone (TDZ) — inutilizzabili fino alla riga che li dichiara.

javascript— editable

Buone pratiche

  • Preferisci const, poi let, evita var. Lo scope di blocco è più prevedibile e previene perdite accidentali e la trappola del ciclo con callback mostrata sopra.
  • Mantieni le variabili nello scope più ristretto possibile. Dichiara all'interno del blocco o della funzione che ne ha bisogno, piuttosto che al livello superiore.
  • Riduci al minimo le variabili globali. Meno variabili globali significa meno conflitti di nomi e meno valori che qualsiasi parte del codice può modificare silenziosamente.
  • Dichiara prima di usare. Anche se l'hoisting esiste, farsi affidamento su di esso rende il codice più difficile da leggere.

Conclusione

Lo scope controlla dove ogni variabile è visibile: globale, di funzione o di blocco. Le funzioni annidate formano un ambiente lessicale che consente al codice interno di risalire verso l'esterno attraverso la catena di scope — il fondamento delle closure. Scegliere let/const rispetto a var offre uno scope di blocco affidabile ed evita le sorprese dell'hoisting. In seguito, studia come le funzioni catturano il proprio contesto nelle Closure JavaScript e come si comportano le funzioni restituite nelle espressioni di funzione.

Esercitazione

Pratica
Quali sono i tipi di scope delle variabili JavaScript?
Quali sono i tipi di scope delle variabili JavaScript?
Was this page helpful?