Javascript: Passing local variables into a dynamically created function that is a parameter inside another function

StackOverflow https://stackoverflow.com/questions/9169353

Question

I am using a function with the following parameterization (which cannot be changed):

my_function(data, callback_function(results, status) {});

I need to pass additional information to callback_function that cannot be added to 'data' (which callback_function uses) or 'results' or 'status'. Specifically this information is the counter of a for loop that the my_function call is in.

To do this I am including a reference to the counter inside the body of callback_function:

for(var i = 0; i < 10; i++) {

  var data = 'cannot modify this data';

  my_function(data, function (results, status) { alert(i); });

}

Unfortunately the final value of i (9 in this case) is being printed 10 times. The intended behavior is for each value of i in the loop (0 through 9) to be printed.

Is it possible for dynamic functions to access variables outside of their scope but within the scope that they are defined?

Was it helpful?

Solution

You need to create a closure that contains the value of i at the time where the anonymous function is created. You can use a wrapper function for that:

function createClosure(x, func) {
  return function(results, status) { func(x, results, status); }
}

/* ... */

for(var i = 0; i < 10; i++) {
  var data = 'cannot modify this data';
  my_function(data, createClosure(i, function(i, results, status) { 
    alert(i);
    alert(results);
    alert(status);
  }));
}

Or if you want to be short, you can create the closure in place:

for(var i = 0; i < 10; i++) {
  var data = 'cannot modify this data';
  my_function(data, (function(i) {
    return function (results, status) { 
      alert(i); 
    }
  })(i));
}

OTHER TIPS

What you need is Function.prototype.bind. Using that you can bind a function to certain parameters. With that in place, your code will look like this:

for(var i = 0; i < 10; i++) {

  var data = 'cannot modify this data';

  function callback(iValue, results, status) { alert(iValue); }
  my_function(data, callback.bind(null, i)); // |null| since you don't seem to need any specific |this|.

}
for(var i = 0; i < 10; i++) {

var data = 'cannot modify this data';

my_function(data, function (results, status) { 
 alert( 
  function(value){ 
    return value;
    }(i);
 )
}   //function (results, status)  ends here
);  // myfunction ends here..

}

Not tested it,but .. try it.. hope it works..

Check this link -> Javascript closures - variable scope question for a better understanding of what you are doing..

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top