非常奇怪的行为与javascript日期,不同的输出在VanillaJS与Vue3相同的代码

ql3eal8s  于 2023-03-24  发布在  Vue.js
关注(0)|答案(1)|浏览(66)

我知道Javascript中的日期很时髦,所以我想我会转移到moment.js,或者因为我在Inertia中做这个项目,我可能会在PHP中处理这个服务器端,以避免添加另一个依赖项。但我仍然觉得这很有趣,所以想在这里发帖,看看我是否能更好地理解我做错了什么。也许我搞砸了与日期无关。
无论如何,我试图填充一个数组与日期元素为每个月给定一个特定的开始日期和数量的月份数组应该持有(在每个元素中递增1个月).我发现了一个被高度好评的stackoverflow帖子,里面有一个我为此偷来的addMonths函数.该函数看起来很直接.然而,它并没有增加一个月更疯狂的是,在我的Vue.js代码中,当我console.log它时,它可以工作,但当我将它推送到一个数组时,它就不行了(使用相同的代码)。
这是密码:

//addMonths came from stack overflow here: https://stackoverflow.com/questions/2706125/javascript-function-to-add-x-months-to-a-date

function addMonths(date, months) {
  let d = date.getDate();
  date.setMonth(date.getMonth() + +months);
  if (date.getDate() !== d) {
      date.setDate(0);
  }
  return date;
}

let starting_date = "2023-03-23";
let months_left = 6;
let header_months = [];
for (let i = 0; i < months_left + 1; i++) {
  let start_date = new Date(starting_date);
  console.log(addMonths(start_date, i));
  header_months.push(addMonths(start_date, i));
}

console.log(header_months);

Codesandbox在这里:https://codesandbox.io/s/thirsty-curran-w3w2cr?file=/src/index.js
如上所述,它增加了2个月,而不是1。

0: Wed Mar 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
1: Mon May 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
2: Sat Jul 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
3: Fri Sep 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
4: Wed Nov 22 2023 18:00:00 GMT-0700 (Mountain Standard Time)
5: Mon Jan 22 2024 18:00:00 GMT-0700 (Mountain Standard Time)
6: Fri Mar 22 2024 18:00:00 GMT-0600 (Mountain Daylight Time)

至少这是一致的和两个console. logs在上面的代码中显示相同的意外结果。我不知道为什么这是错误的。我假设我搞砸了一些与变量范围,而不是start_date重置在每个循环运行它记得最后一个值。如果这是唯一的问题,我可能甚至不张贴问题在这里,只是移动到这样做的另一种方式。但是,我不知道为什么这是错误的。我认为我搞砸了一些与变量范围,而不是start_date重置在每个循环运行它记得最后一个值。如果这是唯一的问题,我可能甚至不张贴问题在这里,而只是移动到这样做的另一种方式。我不知道为什么,但我不知道为什么,但我不知道为什么,但我不知道为什么我会这样做。我不知道为什么,但我不知道为什么我会这样做。我不知道为什么我会这样做。我不知道为什么我会这样做,但我不知道为什么我会这样做。我不知道为什么我会这样做,但我不知道为什么我会这样做。我不知道
更奇怪的是,如果我在实际的Vue3代码中运行它,for循环中的第一个console.log会给我预期的结果:

Show.vue:394 Wed Mar 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
Show.vue:394 Sat Apr 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
Show.vue:394 Mon May 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
Show.vue:394 Thu Jun 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
Show.vue:394 Sat Jul 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
Show.vue:394 Tue Aug 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)

但是header_months数组返回了与Vanilla JS相同的意外结果。

0: Wed Mar 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
1: Mon May 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
2: Sat Jul 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
3: Fri Sep 22 2023 18:00:00 GMT-0600 (Mountain Daylight Time)
4: Wed Nov 22 2023 18:00:00 GMT-0700 (Mountain Standard Time)
5: Mon Jan 22 2024 18:00:00 GMT-0700 (Mountain Standard Time)
6: Fri Mar 22 2024 18:00:00 GMT-0600 (Mountain Daylight Time)

???
我想如果我能找出我做错了什么,这在我的Vue3项目中也会起作用。但是,当运行相同的基本JavaScript代码时,我得到不同的结果,这对我来说是非常奇怪的。不幸的是,因为它是一个更大的内部项目的一部分,我不能在这里分享更大的Vue3代码。但这里有一些截图显示了相关部分:
https://i.imgur.com/ZvYj23C.png
老实说,我对自己印象深刻,我怎么能把这么基本的东西搞砸这么多。有什么想法/想法吗?谢谢!

vzgqcmou

vzgqcmou1#

这个代码段的问题在于日期是可变的,而且在执行console.log时您会同时更改日期:

console.log(addMonths(start_date, i));
//          ^−−−− adds a month to `start_date`

推送到数组时的

header_months.push(addMonths(start_date, i));
//                 ^−−−− adds a _second_ month to `start_date`

所以很自然地,它会增加两次。
如果你想像这样调用它两次,而不用担心双增量,让它把你传入的日期单独留下,而是 * 返回 * 更新的日期:

function addMonths(date, months) {
    let day = date.getDate();
    let result = new Date(date);
    result.setMonth(result.getMonth() + +months);
    if (result.getDate() !== day) {
        result.setDate(0);
    }
    return result;
}

然后你会得到一致的结果:
一个三个三个一个
旁注:在result.getMonth() + +months中不需要一元+。二进制+将执行任何必要的转换,一元是完全冗余的:result.getMonth() + months .

相关问题