La fermeture est créée en raison du fait que vous renvoyez une fonction qui a accès à la variable locale x
, qui a été définie comme le seul membre de la liste des paramètres formels. Donc, les fonctions stockées à a[i]
ont fermé autour de leur x
unique qui était dans la même portée, et en tant que tel, ont accès à lui. Parce que cette variable est accessible uniquement par cette fonction qui a été transmise de la fonction d'auto-appel, vous avez une fermeture.
Je noterais qu'il serait préférable que vous n'utilisiez pas une fonction anonyme auto-invoquante ici car elle est inutile et ajoute un surcoût. Au lieu de déclarer une fonction nommée, et appelez cela.
function foo()
{
var a = [];
function retain_i(x)
{
return function()
{
return x;
}
}
for(var i = 0; i < 3; i++)
{
a[i] = retain_i(i);
}
return a;
}
EDIT: Pour être plus précis à votre question:
la fermeture est créée quand je l'appelle (i) à chaque itération ...
Non, Cela ne crée pas de fermeture. La fermeture est créée lorsque vous renvoient la fonction qui s'est fermée autour du paramètre x
, qui serait autrement inaccessible en dehors de la fonction auto-invoquant.
Si vous n'avez pas retourné cette fonction, vous n'auriez pas de fermeture.
Comme vous pouvez le voir dans l'exemple de code modifié que j'ai donné, la définition/déclaration d'une fonction ne crée pas de fermeture. Plutôt l'exécution d'une fonction qui en sortira une autre fonction qui a accès à des variables autrement inaccessibles crée une fermeture.
Selon le modèle d'environnement, la fermeture est créée * lorsque vous définissez une fonction *. Peu importe si la fermeture survit au contexte survivant ou non. – EFraim