如何在JavaScript中强制对for循环内的变量求值?

如何在JavaScript中强制对for循环内的变量求值?,javascript,Javascript,我目前遇到了一个问题,我动态地创建了一组div,在创建它们的同时,我为它们分配了一个onclick()事件。代码的简化版本如下所示: for(DayOfTheWeek = 0; DayOfTheWeek < 7; DayOfTheWeek++){ var EventCell = document.createElement('div'); var EventDayIndex = WeekNumber*7 + DayOfTheWeek + EventoDayOffset; Eve

我目前遇到了一个问题,我动态地创建了一组div,在创建它们的同时,我为它们分配了一个onclick()事件。代码的简化版本如下所示:

for(DayOfTheWeek = 0; DayOfTheWeek < 7; DayOfTheWeek++){
  var EventCell = document.createElement('div');
  var EventDayIndex = WeekNumber*7 + DayOfTheWeek + EventoDayOffset;
  EventCell.onclick = function(){ClickableDivFunction(EventDayIndex)};
}
function foo() {
  for(DayOfTheWeek = 0; DayOfTheWeek < 7; DayOfTheWeek++){
    var EventCell = document.createElement('div');
    var EventDayIndex = WeekNumber*7 + DayOfTheWeek + EventoDayOffset;
    EventCell.onclick = function(){ClickableDivFunction(EventDayIndex)};
  }
}
然后删除调用函数中的“#”)。 所以我的问题是,你们建议如何以安全、可维护的方式解决这个问题?我假设人们在过去会遇到这个问题,我只是在编程方面没有足够的知识来知道搜索什么,但我能想到的解决这个问题的所有方法要么是,转换为文本,要么是找到一种通过值进行变量赋值的方法


如果您能在这方面提供帮助或提供答案链接,我将不胜感激。

这应该可以做到:

EventCell.onclick = (function (idx) {
    return function () {
        ClickableDivFunction(idx);
    };
}(EventDayIndex));
您看到的“问题”是因为JavaScript提升了您的变量。JavaScript没有块作用域,它唯一的作用域是函数作用域。这意味着您在函数中声明的所有变量都将绑定到函数

您可以编写如下代码:

for(DayOfTheWeek = 0; DayOfTheWeek < 7; DayOfTheWeek++){
  var EventCell = document.createElement('div');
  var EventDayIndex = WeekNumber*7 + DayOfTheWeek + EventoDayOffset;
  EventCell.onclick = function(){ClickableDivFunction(EventDayIndex)};
}
function foo() {
  for(DayOfTheWeek = 0; DayOfTheWeek < 7; DayOfTheWeek++){
    var EventCell = document.createElement('div');
    var EventDayIndex = WeekNumber*7 + DayOfTheWeek + EventoDayOffset;
    EventCell.onclick = function(){ClickableDivFunction(EventDayIndex)};
  }
}
函数foo(){
for(DayOfWeek=0;DayOfWeek<7;DayOfWeek++){
var EventCell=document.createElement('div');
var EventDayIndex=周数*7+周数+事件日偏移量;
EventCell.onclick=function(){ClickableDivFunction(EventDayIndex)};
}
}
但JavaScript会将其编译为:

function foo() {
  var EventCell, EventDayIndex;
  for(DayOfTheWeek = 0; DayOfTheWeek < 7; DayOfTheWeek++){
    EventCell = document.createElement('div');
    EventDayIndex = WeekNumber*7 + DayOfTheWeek + EventoDayOffset;
    EventCell.onclick = function(){ClickableDivFunction(EventDayIndex)};
  }
}
函数foo(){
var EventCell,EventDayIndex;
for(DayOfWeek=0;DayOfWeek<7;DayOfWeek++){
EventCell=document.createElement('div');
EventDayIndex=周数*7+周数+事件日偏移量;
EventCell.onclick=function(){ClickableDivFunction(EventDayIndex)};
}
}
现在您可以了解为什么每个函数都会计算相同的值:因为它们使用相同的变量

如果要捕获循环的状态,需要创建另一个作用域。如前所述,JavaScript的唯一作用域是函数作用域,因此需要创建另一个函数

您可以这样做:

function captureIt(EventDayIndex) {
  return function(){ClickableDivFunction(EventDayIndex)};
}

function foo() {
  var EventCell, EventDayIndex;
  for(DayOfTheWeek = 0; DayOfTheWeek < 7; DayOfTheWeek++){
    EventCell = document.createElement('div');
    EventDayIndex = WeekNumber*7 + DayOfTheWeek + EventoDayOffset;
    EventCell.onclick = captureIt(EventDayIndex);
  }
}
函数captureIt(EventDayIndex){
返回函数(){ClickableDivFunction(EventDayIndex)};
}
函数foo(){
var EventCell,EventDayIndex;
for(DayOfWeek=0;DayOfWeek<7;DayOfWeek++){
EventCell=document.createElement('div');
EventDayIndex=周数*7+周数+事件日偏移量;
EventCell.onclick=captureIt(EventDayIndex);
}
}
或者,您可以使用立即调用的函数表达式(IIFE):

函数foo(){
var EventCell,EventDayIndex;
for(DayOfWeek=0;DayOfWeek<7;DayOfWeek++){
EventCell=document.createElement('div');
EventDayIndex=周数*7+周数+事件日偏移量;
EventCell.onclick=(函数(i){
返回函数(){ClickableDivFunction(i)};
}(EventDayIndex);
}
}

JavaScript通过函数来确定变量的作用域,而不是像您可能习惯的那样通过循环或块来确定变量的作用域。因此,如果您想为每个div单独设置一个变量,则需要单独的函数调用

for(DayOfTheWeek = 0; DayOfTheWeek < 7; DayOfTheWeek++){
  createEventCell(WeekNumber*7 + DayOfTheWeek + EventoDayOffset);
}

function createEventCell(EventDayIndex) {
  var EventCell = document.createElement('div');
  EventCell.onclick = function() { ClickableDivFunction(EventDayIndex); };
}
for(dayOfWeek=0;dayOfWeek<7;dayOfWeek++){
createEventCell(周数*7+DayOfWeek+EventoDayOffset);
}
函数createEventCell(EventDayIndex){
var EventCell=document.createElement('div');
EventCell.onclick=function(){ClickableDivFunction(EventDayIndex);};
}
这是不同的,因为对
createEventCell
的每个调用都有自己的作用域(这是您对原始代码中每个循环的预期结果)


JavaScript使得创建新函数并传递它们变得非常容易,因此最终不会像最初看起来那样麻烦,而且您可能会注意到代码变得更小、更紧凑,重用起来也更有趣。当您更熟悉该语言时,请查看underline.js。

谢谢大家的帮助!