Stavo leggendo la sezione "Chiusure" del tutorial JavaScript di w3schools e non capisco come funziona l'ultimo esempio.
L'obiettivo è creare una variabile "privata" counter
che possa essere modificata solo dalla funzione add
. Ecco il codice:
<!DOCTYPE html>
<html>
<body>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo">0</p>
<script>
var add = (function outer() {
var counter = 0;
return function inner() {return counter += 1;}
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
Ho modificato le due funzioni anonime e le ho denominate outer
e inner
in modo che possano essere più facilmente referenziate. Ecco un link del codice in azione:
Quindi inizialmente la variabile add
è assegnata a un'espressione di funzione autoinvocante. Ciò eseguirà la funzione outer
una volta e imposterà counter
su 0. Quando si fa clic sul pulsante, viene chiamato myFunction
e questo inserisce il valore restituito della funzione add
, il valore counter
aggiornato, all'interno del tag p. Pertanto, facendo clic sul pulsante, il valore della variabile counter
aumenta di 1 ogni evento on-click del pulsante. Non capisco come il valore del valore counter
sia influenzato dalle funzioni outer
e inner
. Questo è il modo in cui l'ho (a torto) capito:
Quando la funzione add
viene chiamata dalla funzione myFunction
(su un evento onclick del pulsante), prima la funzione outer
imposterà la variabile counter
su 0 dalla seguente istruzione:
var counter = 0;
Intuitivamente penserei che il valore di ritorno della funzione add
invocherebbe la funzione inner
(specialmente perché posso vedere questo codice funziona) ma non capisco come. Questa è una domanda che ho. Se lo accetto, la funzione inner
incrementerebbe la variabile counter
di 1. Riesco a vedere come questo abbia senso fare clic sul pulsante che chiama la funzione myFunction
una volta. Per la seconda volta che si fa clic sul pulsante non capisco come non si resetta. Sento che prima del secondo clic la variabile counter
è 1 e quindi sul clic la funzione outer
reimposta la variabile counter
su 0 con questa riga di nuovo:
var counter = 0;
e quindi viene invocata la funzione inner
. Poiché la funzione inner
è nidificata nella funzione outer
, è nel campo di applicazione accedere alla variabile counter
e quindi aumentarla da 0 a 1. Cosa non sto capendo di questo?
Sento che potrei non capire come funziona l'istruzione return
su una funzione, ma non ne sono sicuro. La variabile add
è solo la funzione inner
solo perché è ciò che viene restituito? E come viene richiamato se si trova all'interno di un'istruzione return
? Non capisco come var counter = 0;
non venga eseguito ad ogni clic del pulsante quando viene richiamato myFunction
.
Ho pensato che myFunction
invochi la funzione add
e che esegua la funzione outer
, che esegue var counter = 0;
e quindi la funzione inner
viene restituita e invocata e aumenta la variabile counter
.
Non capisco se restituire una funzione invocherebbe anche la funzione. Inoltre, non so se la creazione e l'assegnazione della variabile add
abbiano avuto qualcosa a che fare con il modo in cui funziona. All'inizio non lo pensavo, ma chi lo sa? Non lo capisco, quindi tutto è possibile per me adesso.