简体   繁体   English

在javascript中声明存储在函数数组中的函数时,为变量赋值

[英]Assign value to a variable when declaring a function stored in a function array in javascript

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. 这里的问题是,当执行函数数组时,参数f_counter是当前的全局变量f_counter,而不是将各个函数添加到函数数组时的f_counter。

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. 我需要一个好的做法,在将f_counter的当前值存储到函数定义中之前将其存储在函数定义中,并且当迭代并执行数组中的函数时,它应该使用存储的值来调用回调函数。

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 ... 有些函数可能有比f_counter更多的变量,依此类推......

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++;

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. 由于您的计数器是标量 ,因此将通过val复制到对象。 Note: it will not work if value is object, because objects passed by reference. 注意:如果value是object,它将不起作用,因为对象通过引用传递。

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. 此外,您可以在传递时使用f_counter ++,因此每次都会增加计数器。

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

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): 召回你的队列(转移)/堆栈(pop):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM