valor - pasar variable de javascript a html
¿Cómo paso el valor(no la referencia) de una variable JS a una función? (6)
Además de los cierres, puedes usar function.bind
:
google.maps.event.addListener(marker, ''click'', change_selection.bind(null, i));
pasa el valor de i
en como argumento a la función cuando se llama. ( null
es para enlazar this
, que no necesita en este caso).
function.bind
fue introducido por el framework Prototype y ha sido estandarizado en ECMAScript Fifth Edition. Hasta que los navegadores lo admitan de forma nativa, puede agregar su propio soporte de function.bind
utilizando cierres:
if (!(''bind'' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
Esta pregunta ya tiene una respuesta aquí:
Aquí hay una versión simplificada de algo que estoy tratando de ejecutar:
for (var i = 0; i < results.length; i++) {
marker = results[i];
google.maps.event.addListener(marker, ''click'', function() {
change_selection(i);
});
}
pero descubro que cada oyente usa el valor de results.length (el valor cuando termina el ciclo for). ¿Cómo puedo agregar oyentes de modo que cada uno use el valor de i en el momento en que lo agregue, en lugar de la referencia a i?
Creo que podemos definir una variable temporal para almacenar el valor de i.
for (var i = 0; i < results.length; i++) {
var marker = results[i];
var j = i;
google.maps.event.addListener(marker, ''click'', function() {
change_selection(j);
});
}
Aunque no lo he probado.
Debe crear un ámbito separado que guarde la variable en su estado actual pasándola como un parámetro de función:
for (var i = 0; i < results.length; i++) {
(function (i) {
marker = results[i];
google.maps.event.addListener(marker, ''click'', function() {
change_selection(i);
});
})(i);
}
Al crear una función anónima y llamarla con la variable como primer argumento, está pasando por valor a la función y creando un cierre.
Estás terminando con un cierre. Aquí hay un artículo sobre cierres y cómo trabajar con ellos. Vea el Ejemplo 5 en la página; ese es el escenario con el que estás lidiando.
EDITAR: Cuatro años después, ese enlace está muerto. La raíz del problema anterior es que el bucle for
formularios cierra (específicamente en marker = results[i]
). Cuando se pasa el marker
a addEventListener
, se ve el efecto secundario del cierre: el "entorno" compartido se actualiza con cada iteración del ciclo, antes de que finalmente se "guarde" a través del cierre después de la iteración final. MDN lo explica muy bien.
cierres
for (var i = 0, l= results.length; i < l; i++) {
marker = results[i];
(function(index){
google.maps.event.addListener(marker, ''click'', function() {
change_selection(index);
});
})(i);
}
EDITAR, 2013: ahora se conocen comúnmente como IIFE
for (var i = 0; i < results.length; i++) {
marker = results[i];
google.maps.event.addListener(marker, ''click'', (function(i) {
return function(){
change_selection(i);
}
})(i));
}