key = "uid"; console.log("#"+key); // #uid
$("#"+key).unbind("click").click( function() { fnc(hl[key][1], direction); });
console.log(key); // uid
key = "inVal"; console.log("#"+key); // #inVal
$("#"+key).unbind("click").click( function() { fnc(hl[key][2], direction); });
console.log(key); // inVal
The problem here is that key
is overwritten by the second assignment before it's used in the first callback. Event callbacks are not called at the same time as their defining function and their defining function does not wait for them to be run. The easiest solution would be to use two separate variables, but since it looks like I'm looking at an unrolled loop and your code actually looks like this:
for(var key in hl){
//compute i
key = "inVal"; console.log("#"+key); // #inVal
$("#"+key).unbind("click").click( function() { fnc(hl[key][i], direction); });
console.log(key); // inVal
}
(if var
is missing, you should add it - undeclared variables reside in the global scope. You don't want them there. In strict mode, they fail completely) (not sure where i
comes from, but let's assume it's generated in each loop before what is seen) you can use an immediately invoked function expression (IIFE) to capture the value into a new variable in a new scope (remember, javascript uses function scopes):
for(var key in hl){
// compute `i`
(function(key, i){
key = "inVal"; console.log("#"+key); // #inVal
$("#"+key).unbind("click").click( function() { fnc(hl[key][i], direction); });
console.log(key); // inVal
})(key,i)
}
now key
and i
inside the loop refer to the IIFE arguments, not to the constantly changing variable variables declared outside the loop.
Also note that: if previous values of i
are not used to generate new ones, then the computation of i
can be moved into the function body. If they are used - please note that the order of object keys is not guaranteed.