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

JavaScript Date对象异常行为:数组存储后日期偏移问题求助

问题原因解析

这个现象的核心是Date对象属于引用类型,再结合你代码里setMonth方法的行为特性,具体原因如下:

  1. 引用类型的存储逻辑
    当执行timeArray.push(startDate)时,数组存入的不是当前日期的“副本”,而是startDate这个Date对象的内存引用地址。数组元素和原startDate指向的是同一个内存对象,后续对原对象的修改会直接同步到数组元素上。

  2. setMonth方法的副作用
    startDate.setMonth(...)方法会直接修改调用它的Date对象本身,它返回的只是修改后日期对应的时间戳数字,而非新的Date对象。你代码里startDate = new Date(startDate.setMonth(...))的逻辑是:先修改当前startDate对象的日期,再用修改后的时间戳创建新Date对象赋值给startDate。

具体执行步骤拆解(以你的示例日期为例)

假设初始startDate为Thu Nov 03 2022:

  • 第一次循环:
    1. timeArray.push(startDate) → 数组存入Nov 03对象的引用
    2. console.log(startDate) → 此时原对象未被修改,打印Nov 03
    3. startDate.setMonth(...) → 直接把原Nov 03对象改成Dec 03,返回对应时间戳
    4. startDate = new Date(...) → 创建新的Dec 03Date对象,赋值给startDate
  • 第二次循环:
    1. timeArray.push(startDate) → 数组存入新的Dec 03对象的引用
    2. console.log(startDate) → 此时新对象未被修改,打印Dec 03
    3. startDate.setMonth(...) → 直接把这个Dec 03对象改成Jan 03,返回对应时间戳
    4. startDate = new Date(...) → 创建新的Jan 03Date对象,此时Jan 03大于lastDate(当年12月31日),循环结束
  • 最后打印timeArray时,数组内的两个元素都是被修改后的对象:第一个是被改成Dec 03的原对象,第二个是被改成Jan 03的第二个对象。

解决方法

如果要让数组保存每次循环的日期快照,需要存入对象的副本而非原引用,修改push逻辑即可:

timeArray.push(new Date(startDate)); // 存入当前日期的独立副本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:50:25