function fun() { var fun = [];
for (var i = 0; i < 10; i++)
fun[i] = function() { return i; }; return fun; }
var fun = fun();
[Link](fun[5]());
Déclaration de la fonction fun:
La fonction fun crée un tableau nommé fun et remplit chaque index avec une fonction
anonyme
La boucle for :
La variable i est déclarée avec var, ce qui signifie qu'elle est globale au contexte de la
fonction et non limitée au bloc de la boucle.
Pour chaque itération, une nouvelle fonction anonyme est assignée à un index du tableau
fun. Chaque fonction fait référence à la même variable i.
Problème avec var:
À la fin de la boucle, la valeur de i est égale à 10, car elle est incrémentée jusqu'à ce qu'elle
échoue au test i < 10.
Toutes les fonctions anonymes dans le tableau font référence à la même variable i. Donc, elles
retourneront toutes la dernière valeur de i, qui est 10.
Retour de la fonction fun:
La fonction retourne le tableau fun, contenant 10 fonctions anonymes.
Chaque fonction retourne la valeur de i, qui est maintenant 10.
Exécution de fun[5]() :
La fonction fun[5] est appelée, mais elle retourne la valeur actuelle de i, soit 10.
Résultat dans la console
10
La bonne réponse est C. 10.
Pour éviter ce comportement
Utilisez let dans la boucle pour créer une nouvelle portée pour chaque itération
Pourquoi i atteint 10 malgré i < 10 ?
Avec var
var est une variable de fonction, pas de bloc. Cela signifie que la même variable i est partagé à
travers toutes les itérations de la boucle.
Lorsque la boucle for termine, la condition i < 10 n'est plus vraie. À ce moment, i a une valeur
de 10 (car après la dernière itération, i est incrémenté à 10 avant que la condition soit
évaluée).
Les fonctions dans le tableau fun capturent la référence à la variable i, et non sa valeur à un
moment donné.
Donc, lorsque les fonctions anonymes sont appelées après l'exécution de la boucle, elles
accèdent à la valeur actuelle de i, qui est 10.
Prenons un exemple pour illustrer ce comportement :
for (var i = 0; i < 10; i++) {
setTimeout(() => [Link](i), 0); // Les 10 appels affichent "10"
La fonction anonyme passée à setTimeout est exécutée après la fin de la boucle.
À ce moment, la valeur de i est déjà incrémentée à 10.
Tous les [Link](i) accèdent à cette même valeur, donc 10 est affiché 10 fois.
Version amélioré avec let
function fun() {
var fun = [];
for (let i = 0; i < 10; i++) { // Utilisation de let
fun[i] = function() {
return i;
};
}
return fun;
}
var fun = fun();
[Link](fun[5]()); // Affichera 5
Résultat dans la console