1

What is the best (or good) practise to store a value in a function variable before the function is added to a function array?

For example, we have a counter:

var f_counter = 0;

... and we have a function array:

var a_func = [];

When we add a function to the array, we can do:

a_func.push(
   function(){
      examplecallbackfunction(f_counter);
   }
);
f_counter++;

Here is the example callback function:

function examplecallbackfunction(c) {
<... code ...>
}

Loop through and execute the function array:

var l = a_func.length;
while (l>0) {
    var fnc=a_func[l-1];
    fnc();
    l--;
}

The problem here is that when executing the function array the argument f_counter is what the current global variable f_counter, and not what f_counter was when the individual functions was added to the function array.

I need a good practise storing the current value of f_counter inside of the function definition before it is assigned to the function array, and when iterating and executing the functions in the array it should for example call the callback function using the value stored.

I need a way to do this without having the individual values stored in global variables because I load stuff async depending on user interaction so I never know "in advance" how many and what type of functions that will be stored in the function array. Some functions could have more variables than f_counter, and so on ...

4 Answers 4

1

Wrap your function in a function that executes when it is pushed into the array. That will form an extra closure around that variable. Right now the closure is around the global variable, so by the time the function is actually executed, that global variable is likely NOT what it was when the function was pushed into the loop.

Here is your code with an extra function wrapped around it; didn't test it, but you should get the idea:

a_func.push(
   (function(counter){
      function() {
          examplecallbackfunction(counter);
      }
   })(f_counter) //execute function immediately
);
f_counter++;
Sign up to request clarification or add additional context in comments.

1 Comment

Great! Thank you, this looks promising and a simple approach, exactly what I was looking for!
1

The first way is to use closures (function returns a function in which your variable is copied to its scope). It's a trick that described SO many times that no need to repeat, so just code

var data = 1;
var wrong = function() { console.info(data); };
var right = (function(properval) { 
    return function() { console.info(properval); };
})(data);
data = 2;
wrong(); // 2 in console
right(); // 1 in console

Second way is to push to your array not function, but object like

a_func.push({
   callback: function(input) { console.info(input); },
   value: f_counter
});

And use it inside cycle like

var data = a_func[l-1];
data.callback(data.value);

Since your counter is scalar, it will be copied to object by val. Note: it will not work if value is object, because objects passed by reference.

Comments

1

You can create a function each time, passing the counter as a parameter. Also, you can use f_counter++ when passing it, so it will increment the counter everytime.

a_func.push(
    (function(i) {
        return function() { examplecallbackfunction(i); }
    })(f_counter++)
);

1 Comment

Thank you! Similar to tau's suggestion, this is the approach I will use
0

A simpler approach without closures would be to simply store an object in your array:

a_func.push({counter:counter, f:function(arg){}});

to recall your queue(shift)/stack(pop):

while(obj=a_func.shift()){ obj.f(obj.counter); }

1 Comment

Very interesting suggestion! I will have a look at this and see if I can use it when I have very different functions added to the same array, perhaps a version of this is possible but I am not sure. It sure suites my example, but I believe the complexity will increase when used in practice

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.