【问题标题】:Javascript object references inside arrays数组内的 Javascript 对象引用
【发布时间】: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)]

所以我提出的两个问题是:

  1. 为什么存储在数组中的对象会随着每个 迭代? (我怀疑这是因为 Javascript 的方式 存储对对象的引用,但解释是 不错)
  2. 为什么循环在第二段代码中运行得太远了?第一个示例显示循环在 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


【解决方案1】:

var tempDate = new Date(); 创建新对象。所以在这个例子中:

var array = [tempDate,tempDate,tempDate,tempDate,tempDate];

array[0]array[1] 是同一个对象

这正是对象在几乎所有编程语言中的工作方式:

var a = tempDate;
var b = tempDate;
var c = b;

(在上面的例子中,a、b、c 和 tempDate 是一样的)


关于问题2:

请看看这个小提琴http://jsfiddle.net/Mqnmm/

新对象tempDate 总是今天,然后你申请setDate()

对于旧对象,在最后一次读写日期之前是 Sat, 31 May 2014 14:23:34 GMT,然后您应用 tempDate.setDate(-1) 将日期设置为上个月的最后 N 天

Subtract days from a date in JavaScript 请查看 Rob Dawley 的回答以正确调整日期

【讨论】:

  • 是的,我是这么想的。这回答了问题 1。现在(考虑到我没有修改循环条件)为什么在第二个示例中循环似乎在过去 8 天结束,而在第一个示例中为 7 天?
猜你喜欢
  • 2017-10-11
  • 2013-03-04
  • 1970-01-01
  • 2019-02-26
  • 2013-04-28
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多