La maggior parte degli sviluppatori JavaScript usa la chiusura consciamente o inconsciamente. Anche se lo fanno inconsciamente, funziona bene nella maggior parte dei casi. Ma conoscere la chiusura fornirà un migliore controllo sul codice quando la usano. E un’altra ragione per imparare la chiusura è che è la domanda più frequente nell’intervista per gli sviluppatori JavaScript.
Prequisito:: Scopo della variabile in JavaScript
Vediamo e comprendiamo la chiusura attraverso un esempio.
Esempio 1:
function
foo()
{
var
b = 1;
function
inner(){
return
b;
}
return
inner;
}
var
get_func_inner = foo();
console.log(get_func_inner());
console.log(get_func_inner());
console.log(get_func_inner());
Spiegazione:La cosa interessante da notare qui è dalla linea numero 9 alla linea numero 12. Alla linea numero 9 abbiamo finito di eseguire la funzione pippo() e l’intero corpo della funzione inner() viene restituito e memorizzato nella var get_func_inner, grazie alla linea 7 return inner.
Possiamo accedere alla variabile b che è definita nella funzione pippo() attraverso la funzione inner() poiché quest’ultima conserva la catena di scope della funzione racchiusa al momento dell’esecuzione della funzione racchiusa cioè la funzione interna conosce il valore della funzione interna.Cioè la funzione interna conosce il valore di b attraverso il suo scope chain.
Questa è la chiusura in azione che è la funzione interna può avere accesso alle variabili della funzione esterna così come tutte le variabili globali.
Output del codice precedente:
Per vedere la variabile e la funzione legata all’interno della chiusura possiamo scrivere come:
console.dir(get_func_inner);
Output:
Come possiamo vedere le variabili all’interno della chiusura nella sezione scope.
Definizione di chiusura:
Nei linguaggi di programmazione, le chiusure (anche chiusure lessicali o chiusure di funzioni) sono tecniche per implementare il binding lessicale dei nomi nei linguaggi con funzioni di prima classe. Operativamente, una chiusura è un record che memorizza una funzione insieme ad un ambiente: una mappatura che associa ogni variabile libera della funzione (variabili che vengono utilizzate localmente, ma definite in un ambito chiuso) con il valore o il riferimento a cui il nome era legato quando la chiusura è stata creata.
-Wikipedia
o
In altre parole, la chiusura viene creata quando una funzione figlia mantiene l’ambiente dello scope padre anche dopo che la funzione madre è già stata eseguita
Ora vediamo un altro esempio.
Esempio 2:
function
foo(outer_arg) {
function
inner(inner_arg) {
return
outer_arg + inner_arg;
}
return
inner;
}
var
get_func_inner = foo(5);
console.log(get_func_inner(4));
console.log(get_func_inner(3));
Spiegazione: Nell’esempio precedente abbiamo usato una funzione parametro piuttosto che una predefinita. Notate che anche quando abbiamo finito l’esecuzione di foo(5) possiamo accedere alla variabile outer_arg dalla funzione interna. E all’esecuzione della funzione interna produciamo la somma di outer_arg e inner_arg come desiderato.
Output:
Ora vediamo un esempio di chiusura all’interno di un ciclo.
In questo esempio vogliamo memorizzare una funzione anonima ad ogni indice di un array.
Esempio 3:
function
outer()
{
var
arr = ;
var
i;
for
(i = 0; i < 4; i++)
{
arr =
function
() {
return
i; }
}
return
arr;
}
var
get_arr = outer();
console.log(get_arr());
console.log(get_arr());
console.log(get_arr());
console.log(get_arr());
Output:
Spiegazione: Hai indovinato la risposta giusta? Nel codice sopra abbiamo creato quattro chiusure che puntano alla variabile i che è una variabile locale della funzione outer. La chiusura non ricorda il valore della variabile, punta solo alla variabile o memorizza il riferimento della variabile e quindi restituisce il valore corrente. Nel codice di cui sopra, quando cerchiamo di aggiornare il valore di esso viene riflesso a tutti perché la chiusura memorizza il riferimento.
Vediamo un modo corretto di scrivere il codice di cui sopra in modo da ottenere diversi valori di i a diversi indici.
Esempio 4:
function
outer()
{
function
create_Closure(val)
{
return
function
()
{
return
val;
}
}
var
arr = ;
var
i;
for
(i = 0; i < 4; i++)
{
arr = create_Closure(i);
}
return
arr;
}
var
get_arr = outer();
console.log(get_arr());
console.log(get_arr());
console.log(get_arr());
console.log(get_arr());
Output:
Spiegazione: Nel codice precedente stiamo aggiornando l’argomento della funzione create_Closure ad ogni chiamata. Quindi, otteniamo diversi valori di i a diversi indici.
Nota: Potrebbe essere un po’ difficile capire subito il concetto di chiusura, ma provate a sperimentare la chiusura in diversi scenari come per la creazione di getter/setter, callback e così via.
Riferimento:
“Object Oriented JavaScript” di Stoyan Stefanov
Questo articolo è stato contribuito da Sumit Ghosh. Se ti piace GeeksforGeeks e vuoi contribuire, puoi anche scrivere un articolo usando contribute.geeksforgeeks.org o inviare il tuo articolo a [email protected]. Vedi il tuo articolo apparire sulla pagina principale di GeeksforGeeks e aiuta altri Geek.