Variabili JavaScript: scope, durata e Temporal Dead Zone

by Anastasia P.
SHARE
Variabili JavaScript: scope, durata e Temporal Dead Zone
© Guida-HTML5.it

Introduzione

Quando si studiano le variabili JavaScript, non è sufficiente sapere che possono contenere stringhe, numeri, booleani, null o undefined. È altrettanto importante capire dove una variabile può essere utilizzata e per quanto tempo rimane disponibile. Questi concetti prendono il nome di scope e lifetime.

Lo scope, cioè l’ambito di visibilità, determina il punto del programma in cui una variabile è accessibile. La durata, invece, indica per quanto tempo quella variabile esiste durante l’esecuzione del codice. Comprendere questi meccanismi aiuta a evitare errori come l’uso di variabili non accessibili, sovrascritture accidentali e riferimenti a variabili dichiarate troppo tardi.

In JavaScript moderno si usano principalmente let e const. Entrambe sono dichiarazioni con block scope: una variabile è disponibile solamente all’interno del blocco delimitato da parentesi graffe, come un’istruzione if, un ciclo o una funzione. La parola chiave var, invece, segue regole più vecchie e può produrre comportamenti meno intuitivi.

Codice completo

// Le variabili dichiarate con let e const hanno block scope
const messaggio = "Valore globale";

function mostraScope(utenteAttivo) {
  // Questa variabile esiste solo dentro la funzione
  const nomeUtente = "Giulia";

  if (utenteAttivo) {
    // Questa variabile esiste solo dentro il blocco if
    let stato = "online";

    console.log(messaggio);   // Accessibile
    console.log(nomeUtente);  // Accessibile
    console.log(stato);       // Accessibile
  }

  // Errore: stato è fuori dal suo blocco
  // console.log(stato);

  // La variabile dichiarata con var non rispetta il block scope
  if (utenteAttivo) {
    var ruolo = "editor";
  }

  // Funziona, perché var ha scope di funzione
  console.log(ruolo);
}

mostraScope(true);

// La Temporal Dead Zone impedisce l´uso prima della dichiarazione
function calcolaPrezzo() {
  // Errore: prezzo è nella Temporal Dead Zone
  // console.log(prezzo);

  const prezzo = 25;
  return prezzo;
}

console.log(calcolaPrezzo());

Spiegazione

Scope globale e scope locale

Una variabile dichiarata fuori da funzioni e blocchi appartiene allo scope globale del file o del modulo. Nel codice dell’esempio, messaggio è accessibile dentro mostraScope, perché uno scope interno può leggere i valori presenti in uno scope esterno.

Il contrario non è valido: una variabile locale non può essere utilizzata dall’esterno. nomeUtente è stata dichiarata dentro la funzione, quindi non può essere letta dopo la chiamata a mostraScope. Questo isolamento è utile perché impedisce alle funzioni di modificare accidentalmente variabili appartenenti ad altre parti dell’applicazione.

Il block scope di let e const

Un blocco è qualsiasi sezione racchiusa tra parentesi graffe. Per esempio, il corpo di un’istruzione if o di un ciclo for è un blocco. Una variabile dichiarata con let o const rimane confinata a quel blocco.

Nel codice, stato viene creata solamente quando utenteAttivo è vero. Anche in questo caso, però, la variabile non è disponibile dopo la parentesi graffa di chiusura dell’if. Se si prova a eseguire console.log(stato), JavaScript genera un ReferenceError.

Perché var può creare problemi

var ha function scope, non block scope. Questo significa che una variabile dichiarata dentro un if rimane disponibile per tutta la funzione che contiene quel blocco. Per questo motivo ruolo può essere utilizzata anche dopo l’istruzione if.

Questo comportamento era comune nel JavaScript precedente a ES2015, ma oggi può rendere il codice più difficile da prevedere. In generale, è preferibile usare const quando il riferimento non deve essere riassegnato e let quando il valore deve cambiare.

Temporal Dead Zone

Le variabili dichiarate con let e const vengono registrate all’interno del loro scope, ma non possono essere utilizzate prima della riga di dichiarazione. L’intervallo tra l’inizio dello scope e la dichiarazione prende il nome di Temporal Dead Zone, abbreviata in TDZ.

Per esempio, nel caso di prezzo, la chiamata a console.log(prezzo) posta prima di const prezzo = 25 causerebbe un errore. La TDZ è una protezione utile: obbliga a dichiarare le variabili prima di utilizzarle e rende più chiara la sequenza logica del programma.

Scope lessicale e funzioni annidate

JavaScript utilizza lo scope lessicale. Una funzione può accedere alle variabili definite nel punto del codice in cui è stata dichiarata, anche se viene eseguita in un altro contesto. Questo comportamento è alla base delle closure.

function creaContatore() {
  let valore = 0;

  return function () {
    valore++;
    return valore;
  };
}

const contatore = creaContatore();

console.log(contatore()); // 1
console.log(contatore()); // 2

La funzione interna continua ad accedere a valore anche dopo la fine di creaContatore. Il valore viene mantenuto perché la funzione conserva un riferimento al proprio ambiente lessicale.

Best practice

  • Usa const come scelta predefinita quando una variabile non deve essere riassegnata.
  • Usa let solo quando il valore deve cambiare, per esempio in un contatore.
  • Evita var nel codice moderno, salvo esigenze specifiche di compatibilità con codice legacy.
  • Dichiara le variabili prima del loro utilizzo per evitare problemi legati alla Temporal Dead Zone.
  • Mantieni le variabili nello scope più piccolo possibile: riduce conflitti e rende il codice più facile da testare.
  • Non creare inutilmente variabili globali: possono essere modificate da molte parti dell’applicazione.
  • Usa nomi descrittivi, come prezzoTotale o utenteAutenticato, invece di nomi generici come x o dato.

Riepilogo

Lo scope stabilisce dove una variabile può essere usata, mentre la sua durata indica per quanto tempo rimane disponibile durante l’esecuzione. let e const rispettano il block scope e sono gli strumenti consigliati nel JavaScript moderno. var ha invece function scope e può rendere meno prevedibile l’accessibilità delle variabili.

La Temporal Dead Zone impedisce di leggere una variabile dichiarata con let o const prima della sua dichiarazione. Applicando queste regole, si ottiene codice più sicuro, leggibile e semplice da mantenere.

Approfondisci con risorse ufficiali

Per approfondire questi argomenti, consulta la documentazione MDN dedicata alle dichiarazioni di variabili JavaScript, allo scope e alle closure. È utile anche leggere la specifica ECMAScript, disponibile sul sito ufficiale ecma-international.org, per studiare il comportamento formale di let, const, var e degli ambienti lessicali.

SHARE