8
votes

Déclaration de Var Javascript dans la boucle

/*Test scope problem*/
var func=function(no){
    //verify no
    alert('setting '+no);

    //timeout to recheck 
    setTimeout(function(){
        alert('test '+no);
    }, 500);
}
for(var i=1; i<3; i++){
    func(i);
}

3 commentaires

J'adore aussi voir une explication détaillée de ce qui se passe sur no de la portée ici.


@Daniel Bingham - SANS S est global, à moins que les truites le font dans une fonction. (Les boucles ne donnent pas de nouvelle portée dans JS.)


@ fig-gnuton oh. Eh bien c'est une explication simple pour cela: D Merci!


4 Réponses :


1
votes

J'aime bien que je puisse avoir tellement de kilométrage de Cette réponse .

Si vous avez besoin d'aide pour appliquer cette réponse, faites le moi savoir. p>

EDIT H2>

Bien sûr. Regardons votre code d'origine. P>

setTimeout(function( value )
{
  // 'value' is closed by the function below
  return function()
  {
    alert('test ' + value );
  }
}( no ) // Here's the magic
, 500 );


1 commentaires

Oui, ne voyant pas comment cela se rapporte à cette question. Pouvez-vous expliquer une fermeture à un développeur C / Java que d'apprendre JavaScript?



2
votes

Ceci est essentiellement identique à votre correctif, mais en utilisant une syntaxe différente pour atteindre le réglage de la scorage.

/*Test scope problem*/
for (var i = 1; i < 3; i++) {
  //declare variables 
  var no = i;
  //verify no 
  alert('setting ' + no);

  //timeout to recheck
  (function() {
    var n = no;
    setTimeout(function() { 
      alert('test ' + n);
    }, 500);
  })();
} 


0 commentaires

1
votes

JavaScript n'a pas de scorage lexical (la boucle pour la boucle ne crée pas de nouvelle portée) et votre solution est la solution de contournement standard. Une autre façon d'écrire cela pourrait être la suivante:

[1, 2].forEach(function(no){
    //verify no
    alert('setting '+no);

    //timeout to recheck 
    setTimeout(function(){
        alert('test '+no);
    }, 500);
})


0 commentaires

13
votes

JavaScript n'a pas de portée bloquante et les déclarations variables sont hissées. Ces faits signifient ensemble que votre code est équivalent à: xxx pré>

au moment où votre fonction Timeout exécute, la boucle est longue terminée, avec n ° code> conservant sa valeur finale de 2. P>

Un moyen de contourner la valeur actuelle de NO code> dans une fonction qui crée un nouveau rappel pour chaque appel à Settimeout code>. Création d'une nouvelle fonction Chaque fois que chaque rappel de SetTimeOut est lié à un contexte d'exécution différent avec son propre ensemble de variables. P>

var no;

/*Test scope problem*/
for(var i=1; i<3; i++){
    //declare variables
    no = i;
    //verify no
    alert('setting '+no);

    //timeout to recheck 
    setTimeout( (function(num) {
            return function() {
                alert('test '+num);
            };
        })(no), 500);
}


1 commentaires

Une excellente réponse, il pense t bien expliquer. Je pensais à l'origine que la portée a toujours fonctionné dans les {} dans JavaScript ainsi la question.