Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

Considere el siguiente código 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]();
    }
};

Las alertas imprimen '3' las tres veces. Quiero un comportamiento diferente: en cada iteración del ciclo, genere una función que imprima el valor actual de i. Es decir. 3 funciones que imprimen diferentes índices.

¿Alguna idea?

¿Fue útil?

Solución

Cree una función anónima que acepte i como parámetro y devuelva esa determinada función:

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 haga algo similar: cree una función anónima que acepte i como parámetro para agregar la función a la matriz:

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

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

Otros consejos

Solo otro enfoque, usando curry :

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

Verifique el fragmento anterior que se ejecuta aquí .

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

No necesita cierre para simplemente generar un valor. Sin embargo, su código debe estar contenido en una función para la contención orientada a objetos. No es necesario llamar a las funciones para ejecutarlas.

Puede colocar el cuerpo de su bucle en una función anónima:

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

Al crear esa función y pasar el valor del bucle de '' i '' como argumento, estamos creando una nueva "i" variable dentro del cuerpo del bucle que esencialmente oculta la `` i '' externa. El cierre que inserta en la matriz ahora ve la nueva variable, cuyo valor se establece cuando se llama a la función de función externa en el primer bucle. Esto podría ser más claro si usamos un nombre diferente cuando creamos la nueva variable ... Esto hace lo mismo:

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

El valor de " iNew " se le asigna 0, luego 1, luego 2 porque el bucle llama inmediatamente a la función.

función (i) {alerta (i)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top