2016-11-08 1 views
1

Je ne comprends pas comment expliquer le code ci-dessous et pourquoi il ne fonctionne pas comme prévu:setTimeout Callback explination

for (var i = 0; i < 16; i++) { 

    setTimeout(function() { 
     console.log(i); 
    }, 1) 

} 

// Prints "16" 16 times 

Une solution à ce serait tout simplement en utilisant let au lieu de var dans la boucle, ou

for (var i = 0; i < 16; i++) { 

    (function (k) { 
     setTimeout(function() { 
      console.log(k); 
     }, 100) 
    })(i) 
} 

// Print "0" to "15" 

une fonction auto-invoquante. Si je pouvais avoir une estimation éclairée, la portée de var serait liée au bloc fonctionnel, ou dans le cas de la portée globale, et les boucles for battraient la pile d'appels que produirait le setTimeout() et depuis Javascript est lexical portée il rappelle toutes ces fonctions comme var i = 16 où d'autre part let i = 16 le gardera au bloc?

+0

'setTimeout' exécute * après * la boucle où' I' est 16. – Li357

+0

S'il vous plaît se référer [Comment fonctionne la fermeture] (http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Rajesh

Répondre

0

Dans le premier exemple, vous avez une fermeture autour de la variable de bouclage i. Dans la seconde, vous évitez cela en faisant une copie de i et en utilisant plutôt k. Éviter la fermeture permet à chaque itération de conserver sa propre valeur au lieu de partager i avec toutes les itérations. L'utilisation de let résoudrait également le problème car cela ferait de la variable de bouclage i, une portée de bloc et cela signifierait qu'à chaque itération, i serait techniquement une variable différente de la précédente, ainsi chaque fonction imbriquée obtiendrait une référence à une valeur différente. Ceci est dû à la portée de JavaScript et à la manière dont les fonctions imbriquées entraînent des fermetures, ce qui a des effets secondaires sur le code lorsque la fonction imbriquée référence des variables d'une fonction d'ordre supérieur ET que la fonction imbriquée a une durée de vie plus longue. parent. Dans votre cas, la fonction référencée par setTimeout va vivre plus longtemps que sa fonction contenant.