Domanda

    

Questa domanda ha già una risposta qui:

         

Considera il seguente codice Javascript:

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]();
    }
};

Gli avvisi stampano '3' tutte e tre le volte. Voglio un comportamento diverso: in ogni iterazione del ciclo genera una funzione che stampa il valore corrente di i. Cioè 3 funzioni che stampano indici diversi.

Qualche idea?

È stato utile?

Soluzione

Crea una funzione anonima che accetta i come parametro e restituisce quella determinata funzione:

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]();
}

O fai qualcosa di simile: crea una funzione anonima che accetta i come parametro per aggiungere la funzione all'array:

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

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

Altri suggerimenti

Solo un altro approccio, usando 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)));
  };
};

Controlla lo snippet sopra in esecuzione qui .

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

Non è necessaria la chiusura per generare semplicemente un valore. Il codice dovrebbe tuttavia essere contenuto in una funzione per il contenimento orientato agli oggetti. Le funzioni non devono essere chiamate per essere eseguite.

Puoi mettere il corpo del tuo loop in una funzione anonima:

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]();
}

Creando quella funzione e passando il valore del loop di " i " come argomento, stiamo creando un nuovo " i " variabile all'interno del corpo del loop che nasconde essenzialmente l'esterno "i". La chiusura che si preme sull'array ora vede la nuova variabile, il cui valore viene impostato quando viene chiamata la funzione di funzione esterna nel primo ciclo. Questo potrebbe essere più chiaro se usiamo un nome diverso quando creiamo la nuova variabile ... Questo fa la stessa cosa:

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]();
}

Il valore di " iNew " viene assegnato 0, quindi 1, quindi 2 perché la funzione viene chiamata immediatamente dal ciclo.

funzione (i) {alert (i)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top