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 rispettare queste regole:
- Gli identificatori possono contenere lettere Unicode, segni di dollaro ($), caratteri trattini bassi (_), cifre (0-9) e persino alcuni caratteri Unicode.
- Gli identificatori non possono contenere spazi vuoti, perché l'analizzatore li utilizza per separare gli elementi di input. Ad esempio, se provi a chiamare una variabile
my Variable
anzichémyVariable
, il parser vede due identificatori,my
eVariable
, e genera un errore di sintassi ("token imprevisto: identificatore"). Gli identificatori devono iniziare con una lettera, un trattino basso (
_
) o un segno di dollaro ($
). Non possono iniziare con cifre, 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, verrebbero consentiti identificativi costituiti solo da numeri, causando conflitti tra i numeri utilizzati come numeri e i numeri utilizzati come identificatori:
let 10 = 20 10 + 5 > ?
Le "parole riservate" che hanno già un significato sintattico non possono essere utilizzate come identificatori.
Gli identificatori non possono contenere caratteri speciali (
! . , / \ + - * =
).
Di seguito non sono riportate regole rigide per la creazione di identificatori, ma si tratta di best practice del settore che semplificano la gestione del codice. Se il tuo progetto specifico ha standard diversi, segui quelli per garantire la coerenza.
Seguendo l'esempio dei metodi e delle proprietà integrati di JavaScript, il Camel Case (stilizzato anche come "camelCase") è una convenzione molto comune per gli identificatori composti da più parole. Le maiuscole iniziali sono la pratica di mettere in maiuscolo la prima lettera di ogni parola tranne la prima per migliorare la leggibilità senza spazi.
let camelCasedIdentifier = true;
Alcuni progetti utilizzano altre convenzioni di denominazione, a seconda del contesto e della natura degli dati. Ad esempio, la prima lettera di un comando viene in genere scritta in maiuscolo, pertanto i nomi dei comandi composti da più parole spesso utilizzano una variante del lettering incamelcase comunemente chiamata "upper camel case" o lettering inPascal.
class MyClass {
}
Gli identificatori devono descrivere in modo conciso la natura dei dati che contengono (ad esempio, currentMonthDays
è un nome migliore di theNumberOfDaysInTheCurrentMonth
) e essere facilmente leggibili a colpo d'occhio (originalValue
è meglio di val
). Gli identificatori myVariable
utilizzati in questo modulo funzionano nel contesto di esempi isolati, ma non sono molto utili nel codice di produzione perché non forniscono informazioni sui dati che contengono.
Gli identificatori non devono essere troppo specifici sui dati che contengono, perché
i loro valori possono cambiare a seconda di come gli script agiscono su questi dati o in base alle
decisioni prese dai futuri manutentori. Ad esempio, una variabile a cui è stato inizialmente assegnato l'identificatore miles
potrebbe dover essere modificata in un valore in chilometri in un secondo momento nel progetto, richiedendo ai manutentori di modificare i riferimenti a quella variabile per evitare confusione futura. Per evitare che ciò accada, usa distance
come identificatore.
JavaScript non assegna alcun privilegio o significato speciale agli identificatori che iniziano con i caratteri underscore (_
), ma in genere vengono utilizzati per indicare che una variabile, un metodo o una proprietà è "privata", ovvero che è destinata esclusivamente all'uso all'interno del contesto dell'oggetto che la contiene e non deve essere acceduta o modificata al di fuori di questo contesto. Si tratta di una convenzione mutuata da altri linguaggi di programmazione e risalente a prima dell'aggiunta delle proprietà private di JavaScript.
Dichiarazione di variabili
Esistono diversi modi per informare JavaScript 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
chiavi di parola indicano all'interprete JavaScript che una stringa di caratteri è un
identificatore che potrebbe contenere un valore.
Quando lavori in una base di codice moderna, utilizza let
anziché var
. var
funziona ancora
nei browser moderni, ma presenta alcuni comportamenti non intuitivi che sono stati definiti nelle
prime versioni di JavaScript e che non potevano essere modificati 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 uguale (=
) per assegnare o riassegnare un valore a una variabile. Puoi farlo
nell'ambito della stessa dichiarazione che la dichiara:
let myVariable = 5;
myVariable + myVariable
> 10
Puoi anche dichiarare una variabile con let
(o var
) senza inizializzarla subito. In questo caso, il valore iniziale della variabile è 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. Il riferimento a una variabile non dichiarata causa un errore.
myVariable
> Uncaught ReferenceError: myVariable is not defined
let myVariable;
myVariable
> undefined
L'associazione di un identificatore a un valore è generalmente chiamata "associazione".
La sintassi che segue le parole chiave let
, var
o const
è chiamata "elenco di associazioni" e consente più dichiarazioni di variabili separate da virgole (che terminano con il punto e virgola previsto). Di conseguenza, i seguenti snippet di codice sono funzionalmente identici:
let firstVariable,
secondVariable,
thirdVariable;
let firstVariable;
let secondVariable;
let thirdVariable;
Per riassegnare il valore di una variabile non viene utilizzato let
(o var
), perché JavaScript
sa già che la variabile esiste:
let myVariable = true;
myVariable
> true
myVariable = false;
myVariable
> false
Puoi riassegnare nuovi valori alle variabili in base ai valori esistenti:
let myVariable = 10;
myVariable
> 10
myVariable = myVariable * myVariable;
myVariable
> 100
Se provi a ridefinire una variabile utilizzando let
in un ambiente di produzione,
verrà visualizzato 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 ridefinizione di let
(e class
), pertanto potresti non vedere lo stesso errore nella console per sviluppatori.
Per preservare la compatibilità con i browser precedenti, var
consente la rideclarazione non necessaria
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 per le costanti
seguono tutte 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 la loro creazione, quindi qualsiasi costante non inizializzata rimarrebbe undefined
per sempre. Se provi a dichiarare una costante senza inizializzala, viene visualizzato 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
) causa 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 proprietà di quell'oggetto 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 immutabile riferimento a un valore di dati mutabile. Sebbene la costante stessa non possa essere modificata, le proprietà dell'oggetto a cui si fa riferimento possono essere alterate, aggiunte o rimosse:
const constantObject = { "firstvalue" : true };
constantObject = false
> Uncaught TypeError: invalid assignment to const 'constantObject'
Quando non prevedi che una variabile venga riassegnata, è buona prassi impostarla come costante. L'utilizzo di const
indica al team di sviluppo o ai futuri responsabili di un progetto di non modificare il valore, per evitare di violare le ipotesi fatte dal codice sul suo utilizzo, ad esempio che una variabile verrà valutata in base a un tipo di dati previsto.
Ambito della 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 stata dichiarata.
A seconda della parola chiave utilizzata per dichiarare una variabile e del contesto in cui la definisci, puoi definire l'ambito delle variabili per gli statement di blocco (ambito blocco), per le singole funzioni (ambito funzione) o per l'intera applicazione JavaScript (ambito globale).
Ambito del blocco
Qualsiasi variabile dichiarata utilizzando let
o const
ha come ambito la istruzione di blocco contenente 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 al di fuori del blocco contenente causa lo stesso errore del tentativo di accedere a una variabile inesistente:
{
let scopedVariable = true;
console.log( scopedVariable );
}
> true
scopedVariable
> ReferenceError: scopedVariable is not defined
Per quanto riguarda JavaScript, una variabile con ambito a livello di blocco non esiste al di fuori del blocco che la contiene. Ad esempio, puoi dichiarare una costante all'interno di un blocco e poi dichiararne un'altra al di fuori del blocco che utilizza lo stesso identificatore:
{
const myConstant = false;
}
const myConstant = true;
scopedConstant;
> true
Sebbene una variabile dichiarata non possa estendersi al blocco principale, è disponibile per tutti i blocchi discendenti:
{
let scopedVariable = true;
{
console.log( scopedVariable );
}
}
> true
Il valore di una variabile dichiarata può essere modificato da 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 di descendenti senza errori, anche se utilizza lo stesso identificatore di una variabile in un blocco principale:
{
let scopedVariable = false;
{
let scopedVariable = true;
}
console.log( scopedVariable );
}
> false
Ambito funzione
Le variabili dichiarate utilizzando var
hanno come ambito la funzione contenitore più vicina
(o il blocco di inizializzazione statica all'interno di una classe).
function myFunction() {
var scopedVariable = true;
return scopedVariable;
}
scopedVariable;
> ReferenceError: scopedVariable is not defined
Questo accade anche dopo aver chiamato una funzione. Anche se la variabile viene inizializzata durante l'esecuzione della funzione, 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 in un'intera applicazione JavaScript, all'interno di tutti i blocchi e le funzioni, per qualsiasi script nella pagina.
Sebbene possa sembrare un valore predefinito auspicabile, le variabili a cui qualsiasi parte di un'applicazione può accedere e modificare possono aggiungere un overhead non necessario o addirittura causare collisioni con variabili presenti in altre parti dell'applicazione con lo stesso identificatore. Questo vale per qualsiasi codice JavaScript coinvolto nel rendering di una pagina, inclusi elementi come librerie di terze parti e analisi degli utenti. Pertanto, è buona prassi evitare di inquinare l'ambito globale, se possibile.
Qualsiasi variabile dichiarata utilizzando var
al di fuori di una funzione principale o utilizzando let
o
const
al di fuori di un blocco principale è 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 dichiararla esplicitamente (ovvero senza
mai utilizzare var
, let
o const
per crearla) esegue l'elevazione della variabile allo scopo
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 delle variabili
Le dichiarazioni di variabili e funzioni vengono elevate nella parte superiore del loro 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 del suo ambito
di contenimento prima di eseguire lo script. Ciò significa che a una variabile dichiarata utilizzando
var
può essere fatto riferimento prima che la variabile venga dichiarata senza riscontrare un
errore:
hoistedVariable
> undefined
var hoistedVariable;
Poiché viene ospitata solo la dichiarazione della variabile, non l'inizializzazione,
le variabili che non sono state dichiarate esplicitamente con var
, let
o const
non vengono sollevate:
unhoistedVariable;
> Uncaught ReferenceError: unhoistedVariable is not defined
unhoistedVariable = true;
Come accennato in precedenza, a una variabile dichiarata, ma non inizializzata, viene assegnato un valore undefined
. Questo comportamento si applica anche alle dichiarazioni di variabili elevate, ma solo a quelle dichiarate utilizzando var
.
hoistedVariable
> undefined
var hoistedVariable = 2 + 2;
hoistedVariable\
> 4
Questo comportamento non intuitivo è in gran parte un retaggio delle decisioni di progettazione prese nelle prime versioni di JavaScript e non può essere modificato senza il rischio di interrompere i siti esistenti.
let
e const
risolvono questo comportamento generando un errore quando si accede a una variabile prima che venga creata:
{
hoistedVariable;
let hoistedVariable;
}
> Uncaught ReferenceError: can't access lexical declaration 'hoistedVariable' before initialization
Questo errore è diverso da "hoistedVariable non è definito", che potresti aspettarti quando provi ad accedere a una variabile non dichiarata. Poiché JavaScript ha sollevato la variabile, sa che verrà creata nell'ambito specificato. Tuttavia, anziché rendere disponibile la variabile prima della sua dichiarazione con un valore di undefined
, l'interprete genera un errore.
Le variabili dichiarate con let
o const
(o class
) si dice che esistano in una "zona morta temporale" ("TDZ") dall'inizio del blocco che le racchiude fino al punto del codice in cui la variabile è dichiarata.
La zona morta temporale rende il comportamento di let
più intuitivo rispetto a var
per gli autori. È inoltre fondamentale per la progettazione di const
. Poiché le costanti non possono essere modificate, una costante spostata nella parte superiore del suo ambito e a cui è stato assegnato un valore implicito di undefined
non può essere inizializzata con un valore significativo.
Verificare di aver compreso
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?