我有一个基本的闭包/“使用闭包”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%的时间是尝试找到正确做事方式的线索。
答案 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就不会被共享,并且每个循环周期都有自己的副本,所以它不会被覆盖。