Variabili

Le variabili sono una struttura di dati che assegna un nome rappresentativo a un valore. Possono contenere dati di qualsiasi tipo.

Il nome di una variabile è chiamato identificatore. Un identificatore valido deve seguire queste regole:

  • Gli identificatori possono contenere lettere Unicode, simboli del dollaro ($), trattini bassi (_), cifre (0-9) e persino alcuni caratteri Unicode.
  • Gli identificatori non possono contenere spazi vuoti, perché il parser utilizza uno spazio vuoto per separare gli elementi di input. Ad esempio, se provi a chiamare una variabile my Variable anziché myVariable, il parser vede due identificatori my e Variable e genera un errore di sintassi ("token imprevisto: identificatore").
  • Gli identificatori devono iniziare con una lettera, un trattino basso (_) o il simbolo del dollaro ($). Non possono iniziare con numeri, per evitare confusione tra numeri e identificatori:

    let 1a = true;
    
    > Uncaught SyntaxError: Invalid or unexpected token
    

    Se JavaScript consentisse i numeri all'inizio di un identificatore, ciò consentirebbe gli identificatori composti solo da numeri, causando conflitti tra numeri utilizzati come numeri e numeri utilizzati come identificatori:

    let 10 = 20
    
    10 + 5
    > ?
    
  • Le "parole riservate" già significative sintatticamente non possono essere utilizzate come identificatori.

  • Gli identificatori non possono contenere caratteri speciali (! . , / \ + - * =).

Le seguenti non sono regole rigide per la creazione di identificatori, ma sono best practice del settore che semplificano la gestione del codice. Se il tuo progetto specifico ha standard diversi, seguili per garantire la coerenza.

Seguendo l'esempio impostato dalle proprietà e dai metodi integrati di JavaScript, camel maiuscole (anch'esso stilizzato come "camelCase") è una convenzione molto comune per gli identificatori composti da più parole. L'uso della maiuscola a inizio parola è la combinazione di maiuscole e minuscole nella prima lettera di ogni parola, tranne che sulla prima, per migliorare la leggibilità senza spazi.

let camelCasedIdentifier = true;

Alcuni progetti utilizzano altre convenzioni di denominazione a seconda del contesto e della natura dei dati. Ad esempio, la prima lettera di una classe in genere è in maiuscolo, per cui i nomi delle classi con più parole utilizzano spesso una variante di cammello, comunemente chiamata "maiuscolo cammello" o Pascal.

class MyClass {

}

Gli identificatori devono descrivere concisamente la natura dei dati che contengono (ad esempio, currentMonthDays è un nome migliore di theNumberOfDaysInTheCurrentMonth) e risultare chiari (originalValue è meglio di val). Gli identificatori myVariable utilizzati in questo modulo funzionano nel contesto di esempi isolati, ma sarebbero molto inutili nel codice di produzione perché non forniscono informazioni sui dati contenuti.

Gli identificatori non dovrebbero diventare troppo specifici sui dati che contengono, perché i loro valori possono cambiare a seconda di come gli script agiscono su quei dati o delle decisioni prese dai futuri gestori della gestione. Ad esempio, potrebbe essere necessario modificare la variabile con l'identificatore miles in origine impostandola su un valore in chilometri nel corso del progetto, richiedendo ai gestori della manutenzione di modificare qualsiasi riferimento a quella variabile per evitare confusione in futuro. Per evitare che questo accada, utilizza invece distance come identificatore.

JavaScript non conferisce alcun privilegio o significato speciale agli identificatori che iniziano con il trattino basso (_), ma in genere vengono utilizzati per indicare che una variabile, un metodo o una proprietà sono "privati", il che significa che sono destinati all'utilizzo solo nel contesto dell'oggetto che li contiene e non deve essere accessibile o modificato al di fuori di questo contesto. Si tratta di una convenzione trasferita da altri linguaggi di programmazione e precede l'aggiunta delle proprietà private di JavaScript.

Dichiarazione delle variabili

Esistono diversi modi per rendere JavaScript sensibile di un identificatore, un processo chiamato "dichiarazione" di una variabile. Una variabile viene dichiarata utilizzando le parole chiave let, const o var.

let myVariable;

Utilizza let o var per dichiarare una variabile che può essere modificata in qualsiasi momento. Queste parole chiave indicano all'interprete JavaScript che una stringa di caratteri è un identificatore che potrebbe contenere un valore.

Quando lavori in un codebase moderno, utilizza let anziché var. var funziona ancora nei browser moderni, ma presenta alcuni comportamenti non intuitivi definiti nelle prime versioni di JavaScript e che non può essere modificato in un secondo momento per preservare la compatibilità con le versioni precedenti. let è stato aggiunto in ES6 per risolvere alcuni problemi con il design di var.

Una variabile dichiarata viene inizializzata assegnando un valore alla variabile. Utilizza un singolo segno di uguale (=) per assegnare o riassegnare un valore a una variabile. Puoi farlo nell'ambito della stessa affermazione che la dichiara:

let myVariable = 5;

myVariable + myVariable
> 10

Puoi anche dichiarare una variabile con let (o var) senza inizializzarla immediatamente. In questo caso, il valore iniziale della variabile sarà undefined finché il codice non le assegna un valore.

let myVariable;

myVariable;
> undefined

myVariable = 5;

myVariable + myVariable
> 10

Una variabile con un valore undefined è diversa da una variabile non definita il cui identificatore non è stato ancora dichiarato. Fare riferimento a una variabile che non hai dichiarata causa un errore.

myVariable
> Uncaught ReferenceError: myVariable is not defined

let myVariable;

myVariable
> undefined

L'associazione di un identificatore a un valore viene generalmente chiamata "associazione". La sintassi che segue le parole chiave let, var o const è denominata "elenco di associazioni" e consente più dichiarazioni di variabili separate da virgole (che terminano con il punto e virgola previsto). Questo rende i seguenti snippet di codice funzionalmente identici:

let firstVariable,
     secondVariable,
     thirdVariable;
let firstVariable;
let secondVariable;
let thirdVariable;

La riassegnazione del valore di una variabile non utilizza let (o var), perché JavaScript sa già che la variabile esiste:

let myVariable = true;

myVariable
> true

myVariable = false;

myVariable
> false

Puoi riassegnare nuovi valori delle variabili in base ai valori esistenti:

let myVariable = 10;

myVariable
> 10

myVariable = myVariable * myVariable;

myVariable
> 100

Se provi a ridichiarare una variabile utilizzando let in un ambiente di produzione, riceverai un errore di sintassi:

let myVariable = true;
let myVariable = false;
> Uncaught SyntaxError: redeclaration of let myVariable

Gli strumenti per sviluppatori dei browser sono più permissivi in merito alla ridichiarazione di let (e class), pertanto potresti non visualizzare lo stesso errore nella console per gli sviluppatori.

Per preservare la compatibilità dei browser precedenti, var consente le ridichiarazioni non necessarie senza errori in qualsiasi contesto:

var myVariable = true;
var myVariable = false;

myVariable\
> false

const

Utilizza la parola chiave const per dichiarare una costante, un tipo di variabile che deve essere inizializzata immediatamente e che non può essere modificata. Gli identificatori delle costanti seguono le stesse regole delle variabili dichiarate utilizzando let (e var):

const myConstant = true;

myConstant
> true

Non puoi dichiarare una costante senza assegnarle immediatamente un valore, perché le costanti non possono essere riassegnate dopo essere state create, di conseguenza qualsiasi costante non inizializzata rimane undefined per sempre. Se provi a dichiarare una costante senza inizializzarla, ricevi un errore di sintassi:

const myConstant;
Uncaught SyntaxError: missing = in const declaration

Il tentativo di modificare il valore di una variabile dichiarata con const nel modo in cui potresti modificare il valore di una variabile dichiarata con let (o var) genera un errore di tipo:

const myConstant = true;

myConstant = false;
> Uncaught TypeError: invalid assignment to const 'myConstant'

Tuttavia, quando una costante è associata a un oggetto, le sue proprietà possono essere modificate.

const constantObject = { "firstvalue" : true };

constantObject
> Object { firstvalue: true }

constantObject.secondvalue = false;

constantObject
> Object { firstvalue: true, secondvalue: false }

Una costante che contiene un oggetto è un riferimento immutabile a un valore dei dati mutabile. Sebbene la costante non possa essere modificata, le proprietà dell'oggetto a cui viene fatto riferimento possono essere modificate, aggiunte o rimosse:

const constantObject = { "firstvalue" : true };

constantObject = false
> Uncaught TypeError: invalid assignment to const 'constantObject'

Quando non prevedi che una variabile venga riassegnata, ti consigliamo di impostarla come costante. L'utilizzo di const indica al team di sviluppo o ai futuri gestori di un progetto di non modificare questo valore, per evitare di violare le ipotesi del codice sul modo in cui viene utilizzato, ad esempio che una variabile verrà infine valutata in base a un tipo di dati previsto.

Ambito variabile

L'ambito di una variabile è la parte di uno script in cui è disponibile. Al di fuori dell'ambito di una variabile, non verrà definita: non come identificatore contenente un valore undefined, ma come se non fosse stato dichiarato.

A seconda della parola chiave utilizzata per dichiarare una variabile e del contesto in cui la definisci, puoi definire l'ambito delle variabili in modo da bloccare istruzioni (ambito blocco), singole funzioni (ambito funzione) o l'intera applicazione JavaScript (ambito globale).

Blocca ambito

L'ambito di qualsiasi variabile dichiarata utilizzando let o const è limitata all'istruzione di blocco più vicina, il che significa che è possibile accedere alla variabile solo all'interno di quel blocco. Il tentativo di accedere a una variabile con ambito a blocchi all'esterno del relativo blocco contenitore provoca lo stesso errore del tentativo di accesso a una variabile che non esiste:

{
    let scopedVariable = true;
    console.log( scopedVariable );
}
> true

scopedVariable
> ReferenceError: scopedVariable is not defined

Per quanto riguarda JavaScript, non esiste una variabile con ambito a blocchi esterno al blocco che la contiene. Ad esempio, puoi dichiarare una costante all'interno di un blocco, per poi dichiarare un'altra costante al di fuori di quel blocco che utilizza lo stesso identificatore:

{
  const myConstant = false;
}
const myConstant = true;

scopedConstant;
> true

Sebbene una variabile dichiarata non possa estendersi nel proprio blocco padre, è disponibile per tutti i blocchi discendenti:

{
    let scopedVariable = true;
    {
    console.log( scopedVariable );
    }
}
> true

Il valore di una variabile dichiarata può essere modificato all'interno di un blocco discendente:

{
    let scopedVariable = false;
    {
    scopedVariable = true;
    }
    console.log( scopedVariable );
}
> true

Una nuova variabile può essere inizializzata con let o const all'interno di un blocco discendente senza errori, anche se utilizza lo stesso identificatore di una variabile in un blocco padre:

{
    let scopedVariable = false;
    {
    let scopedVariable = true;
    }
    console.log( scopedVariable );
}
> false

Ambito funzione

L'ambito delle variabili dichiarate utilizzando var è correlato alla funzione contenitore più vicina (o blocco di inizializzazione statico all'interno di una classe).

function myFunction() {
    var scopedVariable = true;

    return scopedVariable;
}

scopedVariable;
> ReferenceError: scopedVariable is not defined

Ciò avviene anche dopo la chiamata di una funzione. Anche se la variabile viene inizializzata durante l'esecuzione della funzione, questa variabile non è ancora disponibile al di fuori dell'ambito della funzione:

function myFunction() {
    var scopedVariable = true;

    return scopedVariable;
}

scopedVariable;
> ReferenceError: scopedVariable is not defined

myFunction();
> true

scopedVariable;
> ReferenceError: scopedVariable is not defined

Ambito globale

Una variabile globale è disponibile nell'intera applicazione JavaScript, all'interno di ogni blocco e funzione, in qualsiasi script della pagina.

Sebbene questo possa sembrare un valore predefinito auspicabile, le variabili accessibili e modificabili da qualsiasi parte di un'applicazione possono aggiungere overhead non necessario o persino causare collisioni con le variabili altrove in un'applicazione con lo stesso identificatore. Questo vale per tutti i JavaScript coinvolti nel rendering di una pagina, inclusi elementi come librerie di terze parti e analisi degli utenti. Pertanto, è buona norma evitare inquinare l'ambito globale, se possibile.

Qualsiasi variabile dichiarata utilizzando var all'esterno di una funzione padre oppure utilizzando let o const all'esterno di un blocco padre è globale:

var functionGlobal = true; // Global
let blockGlobal = true; // Global

{
    console.log( blockGlobal );
    console.log( functionGlobal );
}
> true
> true

(function() {
    console.log( blockGlobal );
    console.log( functionGlobal );
}());
> true
> true

L'assegnazione di un valore a una variabile senza una dichiarazione esplicita (ovvero, senza mai utilizzare var, let o const per crearla) eleva una variabile nell'ambito globale, anche se inizializzata all'interno di una funzione o di un blocco. Una variabile creata utilizzando questo pattern a volte è chiamata "globale implicita".

function myFunction() {
    globalVariable = "global";

    return globalVariable
}

myFunction()\
> "global"

globalVariable\
> "global"

Sollevamento variabili

Le variabili e le dichiarazioni di funzioni vengono esposte nella parte superiore dell'ambito, il che significa che l'interprete JavaScript elabora qualsiasi variabile dichiarata in qualsiasi punto di uno script e la sposta efficacemente nella prima riga dell'ambito di applicazione prima di eseguire lo script. Ciò significa che è possibile fare riferimento a una variabile dichiarata utilizzando var prima che venga dichiarata, senza che si verifichi un errore:

hoistedVariable
> undefined

var hoistedVariable;

Poiché è ospitata solo la dichiarazione della variabile, non l'inizializzazione, le variabili che non sono state dichiarate esplicitamente con var, let o const non vengono istruite:

unhoistedVariable;
> Uncaught ReferenceError: unhoistedVariable is not defined

unhoistedVariable = true;

Come accennato in precedenza, a una variabile dichiarata ma non inizializzata viene assegnato il valore undefined. Questo comportamento si applica anche alle dichiarazioni di variabili sollevate, ma solo a quelle dichiarate utilizzando var.

hoistedVariable
> undefined

var hoistedVariable = 2 + 2;

hoistedVariable\
> 4

Questo comportamento non intuitivo è in gran parte un blocco delle decisioni di progettazione prese nelle prime versioni di JavaScript e non può essere modificato senza il rischio di danneggiare i siti esistenti.

let e const risolvono questo comportamento generando un errore quando viene eseguito l'accesso a una variabile prima della sua creazione:

{
    hoistedVariable;

    let hoistedVariable;
}
> Uncaught ReferenceError: can't access lexical declaration 'hoistedVariable' before initialization

Questo errore è diverso da quello "hoistedVariable non definito" che potresti aspettarti quando cerchi di accedere a una variabile non dichiarata. Poiché JavaScript ha sollevato la variabile, è consapevole che verrà creata all'interno dell'ambito specificato. Tuttavia, invece di rendere disponibile la variabile prima della sua dichiarazione con un valore undefined, l'interprete genera un errore. Si dice che le variabili dichiarate con let o const (o class) siano presenti in una "zona morta temporale" ("TDZ") dall'inizio del blocco circostante fino al punto nel codice in cui viene dichiarata la variabile.

La zona morta temporale rende il comportamento di let più intuitivo di quello di var per gli autori. Inoltre, è fondamentale per la progettazione di const. Poiché le costanti non possono essere modificate, non è stato possibile inizializzare una costante sollevata in cima all'ambito del suo ambito a cui è stato assegnato un valore implicito undefined con un valore significativo.

Verifica le tue conoscenze

Con quali tipi di caratteri puoi iniziare un identificatore?

Una lettera
Un trattino basso
Una cifra

Qual è il metodo preferito per dichiarare una variabile il cui valore può essere modificato in qualsiasi momento?

lascia
const
var