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

JavaScript嵌套for循环执行两次 日期字段被重复格式化更新问题

问题背景

遍历表单对象的嵌套循环逻辑,按元素childTag字段匹配更新对应变量,其中childTag == 'date'的分支负责格式化日期并回写字段。实际运行时该日期分支重复执行2次,导致formattedDate变量被重复计算赋值,已知遍历对象中仅存在1个childTag值为date的元素。
涉及的对象结构参考:
对象结构示例截图

问题代码
for (let i = 0; i < submitFormData.tabs.length; i++) {
  for (let j = 0; j < submitFormData.tabs[i].elements.length; j++) {
    if (submitFormData.tabs[i].elements[j].childTag == "project_name") {
      projectName = submitFormData.tabs[i].elements[j].value;
    } else if (submitFormData.tabs[i].elements[j].childTag == "location_store") {
      locationStore = ' #' + submitFormData.tabs[i].elements[j].value;
    } else if (submitFormData.tabs[i].elements[j].childTag == "location_street") {
      locationStreet = submitFormData.tabs[i].elements[j].value;
    } else if (submitFormData.tabs[i].elements[j].childTag == "location_city") {
      locationCity = submitFormData.tabs[i].elements[j].value;
    } else if (submitFormData.tabs[i].elements[j].childTag == "location_state") {
      locationState = submitFormData.tabs[i].elements[j].value;
    } else if (submitFormData.tabs[i].elements[j].childTag == "location_zip") {
      locationZip = submitFormData.tabs[i].elements[j].value;
    } else if (submitFormData.tabs[i].elements[j].childTag == "date") {
      if (submitFormData.tabs[i].elements[j].value != "") {
        console.log(submitFormData)
        date = (submitFormData.tabs[i].elements[j].value.substring(0, 10));
        formattedDate = (date.substring(5, 11) + '-' + date.substring(0, 4));
        console.log(formattedDate, 'formatted date')
        submitFormData.tabs[i].elements[j].value = formattedDate;
      }
    }
  }
}
排查&修复方案

核心原因

问题由两个因素共同导致:

  1. 遍历逻辑被重复触发:如果submitFormData是Vue/React等框架的响应式状态,在循环中直接修改原对象的value属性会触发状态更新,若这段遍历逻辑写在组件更新回调、表单change监听等随状态变化重复执行的位置,就会被二次调用。如果是原生JS场景,需检查包裹这段循环的函数是否被重复绑定到多个事件回调中。
  2. 日期处理分支无幂等校验:当前逻辑仅判断值非空就执行格式化,第一次格式化完成后的值依然满足非空判断,逻辑重入时会再次对已经格式化的日期做截取拼接,得到错误结果。

修复代码

  1. 给日期分支增加格式校验,已经格式化过的日期直接跳过,避免重复处理
  2. 若为响应式场景,建议调整逻辑触发时机,或遍历前对目标数据做一次拷贝,避免修改状态导致逻辑重入
for (let i = 0; i < submitFormData.tabs.length; i++) {
  for (let j = 0; j < submitFormData.tabs[i].elements.length; j++) {
    const currentItem = submitFormData.tabs[i].elements[j]
    switch(currentItem.childTag) {
      case "project_name":
        projectName = currentItem.value;
        break;
      case "location_store":
        locationStore = ' #' + currentItem.value;
        break;
      case "location_street":
        locationStreet = currentItem.value;
        break;
      case "location_city":
        locationCity = currentItem.value;
        break;
      case "location_state":
        locationState = currentItem.value;
        break;
      case "location_zip":
        locationZip = currentItem.value;
        break;
      case "date":
        // 仅处理原始YYYY-MM-DD格式开头的日期值,跳过已格式化内容
        if (currentItem.value && /^\d{4}-\d{2}-\d{2}/.test(currentItem.value)) {
          const dateStr = currentItem.value.substring(0, 10);
          formattedDate = `${dateStr.substring(5, 7)}-${dateStr.substring(8, 10)}-${dateStr.substring(0, 4)}`;
          currentItem.value = formattedDate;
        }
        break;
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:57:34