【发布时间】:2014-06-05 14:10:43
【问题描述】:
我刚刚注意到我的一个数组中有一些奇怪的行为。我确信问题在于 Javascript 如何将对象引用存储在数组中。我将用我发布的一些代码来演示这个问题,作为对 SO 上另一个问题的回答。该代码只是循环获取今天的日期和该月的前 6 个日期,非常不言自明。
var dates = [];
var date = new Date();
for (var i = 0; i < 7; i++){
var tempDate = new Date();
tempDate.setDate(date.getDate()-i);
dates.push(tempDate);
}
console.log(dates);
输出:[Thu Jun 05 2014 14:54:14 GMT+0100 (GMT Daylight Time),
Wed Jun 04 2014 14:54:14 GMT+0100 (GMT Daylight Time),
Tue Jun 03 2014 14:54:14 GMT+0100 (GMT Daylight Time),
Mon Jun 02 2014 14:54:14 GMT+0100 (GMT Daylight Time),
Sun Jun 01 2014 14:54:14 GMT+0100 (GMT Daylight Time),
Sat May 31 2014 14:54:14 GMT+0100 (GMT Daylight Time),
Fri May 30 2014 14:54:14 GMT+0100 (GMT Daylight Time)]
这是正确的,并且是意料之中的,因为 tempDate 在循环内不断地重新创建为新的 Date 对象。
但是,当我将 tempDate 从循环中取出时,它似乎会在循环的每次迭代中更新数组中的所有对象(而且循环似乎持续了一个 Month 和 1 个 天 离 4 月 29 日太远了):
var dates = [];
var date = new Date();
var tempDate = new Date();
for (var i = 0; i < 7; i++){
tempDate.setDate(date.getDate()-i);
dates.push(tempDate);
}
console.log(dates);
输出:[Tue Apr 29 2014 14:52:21 GMT+0100 (GMT Daylight Time),
Tue Apr 29 2014 14:52:21 GMT+0100 (GMT Daylight Time),
Tue Apr 29 2014 14:52:21 GMT+0100 (GMT Daylight Time),
Tue Apr 29 2014 14:52:21 GMT+0100 (GMT Daylight Time),
Tue Apr 29 2014 14:52:21 GMT+0100 (GMT Daylight Time),
Tue Apr 29 2014 14:52:21 GMT+0100 (GMT Daylight Time),
Tue Apr 29 2014 14:52:21 GMT+0100 (GMT Daylight Time)]
所以我提出的两个问题是:
- 为什么存储在数组中的对象会随着每个 迭代? (我怀疑这是因为 Javascript 的方式 存储对对象的引用,但解释是 不错)
- 为什么循环在第二段代码中运行得太远了?第一个示例显示循环在 7 次成功迭代后结束,即 5 月 30 日(过去 7 天),第二个示例显示迭代后的结果日期为 4 月 29 日 - 距过去一个多月。为什么?
编辑:我有一个基本的jsfiddle,用于测试代码。
【问题讨论】:
-
这就是大多数语言的行为方式......第一个代码在每次迭代中创建一个新的日期对象,第二个代码只创建一个(一个)日期对象,然后在每次迭代中更新它的值。该数组只是多次包含相同的日期对象。
-
是的,我是这么想的。这回答了问题 1。现在(考虑到我没有修改循环条件,为什么在第二个示例中循环似乎在过去 8 天结束,而在第一个示例中为 7 天?
-
我现在……很困惑。这不仅仅是过去 8 天的结束,而是过去整整一个月的结束。我的意思是...我不确定 wtf 刚刚发生在这里。
-
过去还不到一个月。今天是 5 月 5 日,在第一个示例中结束了 7 天(所以是 4 月 30 日)——这是正确的。在第二个示例中,它结束于过去 8 天,即 4 月 29 日。无论如何,它将在 4 月结束,因为我们是本月的第 5 天,减去 7 天。
-
上次我检查是 6 月 5 日... 从 6 月到 4 月之间有一个月。但无论如何,我知道为什么会发生这种情况:Date#setDate 只设置月份中的哪一天。所以在最后一次迭代中,将 tempDate 的月份移到了 May,然后调用 setDate(-1),它会减少月份并再次设置日期。
标签: javascript arrays loops object