JavaScript Date对象异常行为:数组存储后日期偏移问题求助
问题原因解析
这个现象的核心是Date对象属于引用类型,再结合你代码里setMonth方法的行为特性,具体原因如下:
引用类型的存储逻辑
当执行timeArray.push(startDate)时,数组存入的不是当前日期的“副本”,而是startDate这个Date对象的内存引用地址。数组元素和原startDate指向的是同一个内存对象,后续对原对象的修改会直接同步到数组元素上。setMonth方法的副作用startDate.setMonth(...)方法会直接修改调用它的Date对象本身,它返回的只是修改后日期对应的时间戳数字,而非新的Date对象。你代码里startDate = new Date(startDate.setMonth(...))的逻辑是:先修改当前startDate对象的日期,再用修改后的时间戳创建新Date对象赋值给startDate。
具体执行步骤拆解(以你的示例日期为例)
假设初始startDate为Thu Nov 03 2022:
- 第一次循环:
timeArray.push(startDate)→ 数组存入Nov 03对象的引用console.log(startDate)→ 此时原对象未被修改,打印Nov 03startDate.setMonth(...)→ 直接把原Nov 03对象改成Dec 03,返回对应时间戳startDate = new Date(...)→ 创建新的Dec 03Date对象,赋值给startDate
- 第二次循环:
timeArray.push(startDate)→ 数组存入新的Dec 03对象的引用console.log(startDate)→ 此时新对象未被修改,打印Dec 03startDate.setMonth(...)→ 直接把这个Dec 03对象改成Jan 03,返回对应时间戳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
相关产品推荐
相关产品推荐

