Même après avoir lu Vous ne connaissez pas JS et JavaScript: The Core Je ne comprenais toujours pas le comportement du code suivant.
Pourquoi, quand j'appelle counter()()
, je n'obtiens aucune fermeture, mais si j'affecte une variable au résultat de counter()
, comme var getClosure = counter()
, j'obtiens alors un fermeture lors de l'appel de getClosure()
?
function counter() {
var _counter = 0;
function increase() { return _counter++ }
return increase;
}
// Double ()() to call the returned function always return 0, so no closure.
counter()() // returns 0
counter()() // returns 0
counter()() // returns 0
counter()() // returns 0
var createClosure = counter();
createClosure() // returns 0
createClosure() // returns 1
createClosure() // returns 2
createClosure() // returns 3
_counter
Est la variable locale dans la fonction counter()
. Chaque fois que vous appelez counter()
, un nouveau _counter
Sera créé.
Mais var createClosure = counter()
n'a appelé la fonction qu'une seule fois, c'est pourquoi _counter
N'est pas nouvellement créé à chaque fois et "mémorisé" là (c'est là que la fermeture se produit)
A chaque fois vous appelez counter()()
, cela crée une nouvelle fonction et une nouvelle fermeture. Le résultat est donc toujours 0
.
Au contraire, lorsque var createClosure = counter();
est exécutée, une fonction et une fermeture sont créées et enregistrées dans la variable createClosure
. La prochaine fois que vous appellerez createClosure()
, celle enregistrée est invoquée et la fermeture créée est utilisée. Par conséquent, les résultats sont 0
, 1
, 2
, 3
, ...
En d'autres termes, la valeur de retour de la fonction counter()
, qui est la fermeture, n'est pas persistée ou plutôt elle est ignorée lorsque vous appelez simplement la fonction telle quelle.
Cependant, après avoir affecté cette valeur de retour à var createClosure
. Vous pouvez appeler la fermeture autant de fois que nécessaire