如何在JavaScript中更改干扰所需结果的闭包?

时间:2014-01-10 15:57:17

标签: javascript closures

我有一个基本的闭包/“使用闭包”JavaScript问题。

我在一个函数和两个for循环中,我想用一个变量等于循环内部的变量进行Ajax调用。 matches_date设置为一个JavaScript日期,其自定义修改的setTime()在每次循环时都是不同的。在内循环里面,我有:

jQuery('.hide-instance').click(function(event)
  {
  jQuery.ajax('/save/hide/instance', {'complete': function()
    {
    jQuery.ajax('/load/calendar', {'complete':
      DASHBOARD.load_calendar_from_ajax, 'type': 'POST'});
    }, 'data':
    {
    'id': element.id,
    'date': matches_date.toDateString()
    }, 'type': 'POST'});
  });

这是可以预料的,导致hide-instance复选框调用函数,其中hash中的'date'等于最后一次运行循环在循环中的matches_date的最后一个值调用toDateString()。

我已经尝试将matches_date.toDateString()复制到函数之前声明的var,但它没有相同的效果。

如何更改我的代码,以便字典中的'date'填充为定义的循环迭代的toDateString()值?

- 编辑 -

上面引用的调用是在函数内的两个嵌套循环中:

DASHBOARD.load_calendar = function(json)
  {
  console.log('Loading calendar...');
  DASHBOARD.calendar_entries = JSON.parse(json);
  var last_unique_event = 0;
  var is_unique = false;
  var last_day_displayed = '';
  jQuery('#display').html('');
  for(var days_difference = 0; days_difference - last_unique_event <
    DASHBOARD.calendar_days; ++days_difference)
    {
    var matches_date = new Date();
    matches_date.setTime(matches_date.getTime() + days_difference * 24 * 60 *
      60 * 1000);
    for(var index = 0; index < DASHBOARD.calendar_entries.length; ++index)
      {

P.S。我在自己构建的代码上看到了一个使用eval()的方法,所以它不会是不受信任的代码上的eval(),但作为规则,如果我看到做某事的唯一方法是使用eval( ),99%的时间是尝试找到正确做事方式的线索。

1 个答案:

答案 0 :(得分:2)

添加一个闭包:

for(...){
  var matches_date = ...
  (function(matches_date){  //This line does the magic!    
    jQuery('.hide-instance').click(function(event)
      {
      jQuery.ajax('/save/hide/instance', {'complete': function()
        {
        jQuery.ajax('/load/calendar', {'complete':
          DASHBOARD.load_calendar_from_ajax, 'type': 'POST'});
        }, 'data':
        {
        'id': element.id,
        'date': matches_date.toDateString()
        }, 'type': 'POST'});
      });
  })(matches_date);  //This one, too
}

由于javascript vars作用域是函数级的,我们在循环中添加一个函数(闭包),它有自己的matches_date var(作为参数)。这样var就不会被共享,并且每个循环周期都有自己的副本,所以它不会被覆盖。

来自玻利维亚拉巴斯的欢呼声