Question

    

Cette question a déjà une réponse ici:

         

Considérez le code Javascript suivant:

var a = [];

var f = function() {

    for (var i = 0; i < 3; i++) {
        a.push(function(){alert(i)});
    }
    for (var j = 0; j < 3; j++) {
        a[j]();
    }
};

Les alertes affichent "3" toutes les trois fois. Je veux un comportement différent - à chaque itération de la boucle, générez une fonction qui affiche la valeur actuelle de i. C'est à dire. 3 fonctions imprimant différents index.

Des idées?

Était-ce utile?

La solution

Créez une fonction anonyme qui accepte i en tant que paramètre et renvoie cette certaine fonction:

for (var i = 0; i < 3; i++) {
    a.push((function(i) {
        return function() {
            alert(i);
        }
    })(i));
}

for (var j = 0; j < 3; j++) {
    a[j]();
}

Ou faites quelque chose de similaire: créez une fonction anonyme qui accepte i en tant que paramètre pour ajouter la fonction au tableau:

for (var i = 0; i < 3; i++) {
    (function(i) {
        a.push(function() {
            alert(i);
        });
    })(i);
}

for (var j = 0; j < 3; j++) {
    a[j]();
}

Autres conseils

Juste une autre approche, en utilisant currying :

var a = [];
var f = function() {
    for (var i = 0; i < 3; i++) {
        a.push((function(a){alert(a);}).curry(i));
    }
    for (var j = 0; j < 3; j++) {
        a[j]();
    }
};

// curry implementation
Function.prototype.curry = function() {
  var fn = this, args = Array.prototype.slice.call(arguments);
  return function() {
    return fn.apply(this, args.concat(
      Array.prototype.slice.call(arguments)));
  };
};

Vérifiez l'extrait de code ci-dessus qui exécute ici .

var iterate = (function () {
    var i, j = [];
    for (i = 0; i < 3; i += 1) {
        j.push(i);
        alert(j[j.length - 1]);
    }
}());

Vous n'avez pas besoin de la fermeture pour simplement afficher une valeur. Votre code doit cependant être contenu dans une fonction de confinement orienté objet. Les fonctions ne doivent pas nécessairement être appelées pour être exécutées.

Vous pouvez placer le corps de votre boucle dans une fonction anonyme:

var a = [];

for(var i = 0; i < 3; i++) (function(i) {
    a.push(function() { alert(i); });
})(i)

for(var j = 0; j < 3; j++) {
    a[j]();
}

En créant cette fonction et en transmettant la valeur de "i" à la boucle. comme argument, nous créons un nouveau " i " variable à l'intérieur du corps de la boucle qui cache essentiellement le "i" extérieur. La fermeture que vous appuyez sur le tableau voit maintenant la nouvelle variable, dont la valeur est définie lorsque la fonction de fonction externe est appelée dans la première boucle. Cela pourrait être plus clair si nous utilisons un nom différent lorsque nous créons la nouvelle variable ... Ceci fait la même chose:

var a = [];

for(var i = 0; i < 3; i++) (function(iNew) {
    a.push(function() { alert(iNew); });
})(i)

for(var j = 0; j < 3; j++) {
    a[j]();
}

La valeur de " iNew " est assigné 0, puis 1, puis 2 car la fonction est appelée immédiatement par la boucle.

fonction (i) {alerte (i)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top