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 identificatorimy
eVariable
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?
Qual è il metodo preferito per dichiarare una variabile il cui valore può essere modificato in qualsiasi momento?