JavaScript仅将for循环中的最后一个条目推送到对象

时间:2019-01-04 16:13:04

标签: javascript arrays object

我有以下代码来填充viewData对象:

month = 1;
year = 2019;
days = 31;

// data object for return data
var viewData = {
 entries: []
};

// temp data stores
var jsonData = {};
var dict = {};

for (var i = 0; i < days; i++) {
  var dArr = [year, month, i+1];
  var storeDate = dArr.join("-");
  dict[storeDate] = 0;
}

for (var j in rows) { // I get rows from a SQL call, it works

    var fullString = formatDate(rows[j].EndTime); // this just uses a function to format a date
    var theDate = fullString.split(" "); // this get a date in the format YYYY-MM-dd
    dict[theDate] = dict[theDate] + rows[j].TotalDuration; // add the current duration to relevant dictionary entry
}

for (var p = 0; p < days; p++) {
  // create the date string for dictionary reference 
  var dArr = [year, month, p+1];
  var storeDate = dArr.join("-");

  // populate the jsonData object
  jsonData['timestamp'] = storeDate;
  jsonData['duration'] = dict[storeDate];
  // push the jsonData object to the viewData object
  console.log('---------------------------');
  console.log('Timestamp: ', jsonData['timestamp']);
  console.log('Duration: ', jsonData['duration']);
  viewData.entries.push(jsonData);
}

因此从这段代码中,当我在for循环中打印出时间戳和持续时间时,我得到了正确的值(例如“ timestamp”:“ 2019-01-04,” duration“:0)。我解析并打印了viewData对象,获得了所有时间戳记值为“ 2019-01-31”且持续时间为“ 0”的条目。这些值仅与for循环的最后一次迭代有关。

因此,似乎仅使用for look的最后一次迭代的时间戳和持续时间值填充了viewData对象中的所有条目。

为什么会这样?是否有与我在这里不了解的javascript工作原理相关的东西?

2 个答案:

答案 0 :(得分:1)

查看这两行

 jsonData['timestamp'] = storeDate;
 jsonData['duration'] = dict[storeDate];

jsonData['timestamp']jsonData['duration']是特定的键/值对,每次迭代时都要覆盖它们。然后,当您在最后一行中推送它时,它仅推送对对象的引用,而不是实际对象。 console.log并没有像您想要的那样同步发生,因此有时在实际记录日志时,它仅显示更新的对象。您可以这样做:

jsonData[p] = {};
jsonData[p].timestamp = storeDate;
jsonData[p].duration = dict[storeDate];

另一种选择是将jsonData对象或{timestamp, duration}数组推入到数组[timestamp, duration]中。

此外,您可以将这两行变成

var dArr = [year, month, p+1];
var storeDate = dArr.join("-");

使用模板字符串插入一行

var storeDate = `${year}-${month}-{p+1}`;

答案 1 :(得分:0)

viewData.entries.push(jsonData);将对象“ jsonData”的引用推送到数组,而不是副本。这意味着当您更改对象jsonData时,推送到数组的引用也将更改。