I am prob. being pretty dense here but I can’t figure out exactly what is going on in the code below.
What I am trying to do is attach two, separate, handlers to the change event of a field. Each handler is set up by looping over an array and using the items in the array to effect the output of the handler when it runs – hopefully will become clear when you look at the example code.
Code follows:
$(document).ready( function () {
//
// Create some test input fields on the page...
//
$('<br />').insertAfter($('body > *:last'));
$('<input type="text" name="t0" id="t0" value="" />').insertAfter($('body > *:last'));
$('<input type="text" name="t1" id="t1" value="" />').insertAfter($('body > *:last'));
//
// The problematic part - for me at least...
//
var arr = new Array(1, 2);
for (var a in arr) {
// Using Chrome console here for logging
console.log("## " + a);
$('#t0').change(function () {
console.log(">> " + a)
});
}
});
So what I would expect to happen when I add a value to the first field is, from within the console (running these examples within Chrome):
## 0
## 1
>> 1
>> 2
What I get is:
## 0
## 1
>> 1
>> 1
I would have expected the function passed to the handler would form a closure over the value of a and I would end up with two functions being bound to the handler, one in which a had the value 1 and one in which a had the value 2.
Ideas?
Cheers – kris
There are two big mistakes here:
First of all, the
for (a in x)doesn’t work like you expect it to: it iterates over object properties, not over array elements.The other mistake is that
achanges by the time the function gets called. A good way to achieve the desired functionality is like this:To see what happens with the
forloop if you don’t create a closure, see this:Now all the functions will log
3, which is the index of the last element in the array + 1 (arr[0] == 1, arr[1] == 2, arr[2] == 3). What happens is that theforloop creates those functions at each iteration, but they get executed after the loop finishes, whena == arr.length.