Search code examples
javascriptparameter-passingdynamic-function

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


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?


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