You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环中重复声明变量继承旧数组属性问题——工时模式日期截断异常

问题

我有两个数组:organHolidayYears(存储年度的起始与结束日期)和sortedUserWorkingPatterns(存储员工常规工作日及排班模式的启用、停用日期)。我需要把排班模式绑定到对应的年度数组中,并截断排班模式的起止日期以匹配绑定的年度。

举个例子:如果员工某排班模式是2021年7月至2022年6月,那么这个模式要绑定到2021年(起止为2021年7月-12月),同时绑定到2022年(起止为2022年1月-6月)。

我写了嵌套循环遍历年度和排班模式,按需绑定,但截断后的起止日期被覆盖了。比如上面的例子里,2021和2022年度的排班模式起止日期都变成了2022年1月和2021年12月。我每次循环都重新声明了workingPatternsTemp变量,但它还是继承旧循环的属性,请问原因和解决方法?

代码如下:

for (let j = 0; j < organHolidayYears.length; j++) { //cycle through holiday years and attach working patterns
  var holidayYear = organHolidayYears[j];
  for (let i = 0; i < sortedUserWorkingPatterns.length; i++) { // cycle through working patterns and attach to given year if necessary
    var workingPatternsTemp = sortedUserWorkingPatterns[i];
    var toDate = holidayYear.unixEndDate; //holiday year end date
    var fromDate = holidayYear.unixStartDate; //holiday year start date
    var workingPatternStartDate = workingPatternsTemp.unixStartDate;
    var workingPatternEndDate = workingPatternsTemp.unixEndDate;
      // CASE 1: PATTERN STARTS DURING YEAR
      if (workingPatternStartDate <= toDate && workingPatternStartDate >= fromDate) {
        // CASE 1a: PATTERN ENDS DURING YEAR
        if (workingPatternEndDate <= toDate) {
          holidayYear.workingPatterns.push(workingPatternsTemp); // add working pattern to holiday year
        }
        // CASE 1b: PATTERN ENDS AFTER YEAR
        else  {
          workingPatternsTemp.unixEndDateInHolidayYear = toDate; // truncate working pattern at end of year
          holidayYear.workingPatterns.push(workingPatternsTemp); // add working pattern to holiday year
        }
      // CASE 2: PATTERN ENDS DURING YEAR (BUT DOES NOT START DURING YEAR) 
      } else if (workingPatternEndDate <= toDate && workingPatternEndDate >= fromDate) {
          workingPatternsTemp.unixStartDateInHolidayYear = fromDate; // truncate working pattern at start of holiday year
          holidayYear.workingPatterns.push(workingPatternsTemp); // add working pattern to holiday year
      }
      // CASE 3: PATTERN DOES NOT OVERLAP YEAR
      else {}
  }
}
原因分析

核心问题是引用类型的赋值特性:workingPatternsTemp = sortedUserWorkingPatterns[i]并没有创建新对象,只是把原数组里的排班模式对象的引用赋值给了workingPatternsTemp。你每次修改workingPatternsTemp的属性(比如unixEndDateInHolidayYear),其实是直接修改了原数组sortedUserWorkingPatterns里的对应对象。当下一次循环处理另一个年度时,这个对象已经被上一次的修改污染,导致后续绑定的年度拿到的是已修改过的对象,最终出现日期覆盖的问题。

解决方法

每次处理排班模式时,不要直接使用原对象的引用,而是创建原对象的拷贝(浅拷贝或深拷贝,根据对象结构选择),修改拷贝后的对象属性再添加到年度数组中。

具体实现方式:

  1. 浅拷贝:如果排班模式对象没有嵌套的子对象,用对象展开语法或Object.assign创建拷贝:
// 替换原有的 var workingPatternsTemp = sortedUserWorkingPatterns[i];
var workingPatternsTemp = {...sortedUserWorkingPatterns[i]};
// 或者用 Object.assign
// var workingPatternsTemp = Object.assign({}, sortedUserWorkingPatterns[i]);
  1. 深拷贝:如果排班模式对象有嵌套的子对象(比如内部还有数组或对象),用深拷贝,比如JSON.parse(JSON.stringify())(注意:该方法不支持函数、Symbol等特殊类型):
var workingPatternsTemp = JSON.parse(JSON.stringify(sortedUserWorkingPatterns[i]));

修改后的完整代码示例:

for (let j = 0; j < organHolidayYears.length; j++) {
  var holidayYear = organHolidayYears[j];
  for (let i = 0; i < sortedUserWorkingPatterns.length; i++) {
    // 创建原对象的浅拷贝,避免修改原数据
    var workingPatternsTemp = {...sortedUserWorkingPatterns[i]};
    var toDate = holidayYear.unixEndDate;
    var fromDate = holidayYear.unixStartDate;
    var workingPatternStartDate = workingPatternsTemp.unixStartDate;
    var workingPatternEndDate = workingPatternsTemp.unixEndDate;

    if (workingPatternStartDate <= toDate && workingPatternStartDate >= fromDate) {
      if (workingPatternEndDate <= toDate) {
        holidayYear.workingPatterns.push(workingPatternsTemp);
      } else {
        workingPatternsTemp.unixEndDateInHolidayYear = toDate;
        holidayYear.workingPatterns.push(workingPatternsTemp);
      }
    } else if (workingPatternEndDate <= toDate && workingPatternEndDate >= fromDate) {
      workingPatternsTemp.unixStartDateInHolidayYear = fromDate;
      holidayYear.workingPatterns.push(workingPatternsTemp);
    }
  }
}

这样每次循环处理的都是独立的拷贝对象,修改属性不会影响原数组中的对象,也不会被后续循环覆盖之前的修改结果。

内容的提问来源于stack exchange,提问作者rainybird

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 11:30:51