Javascript выдвигая только последнюю запись в цикле для объекта - PullRequest
0 голосов
/ 04 января 2019

У меня есть следующий код для заполнения объекта 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, я получаю правильные значения (например, «метка времени»: «2019-01-04,« продолжительность »: 0). Но когда Я разрешаю и распечатываю объект viewData, получаю все записи со значением метки времени «2019-01-31» и длительностью «0». Эти значения относятся только к последней итерации цикла for.

Таким образом, создается впечатление, что все записи в объекте viewData заполняются только значениями меток времени и продолжительности последней итерации для поиска.

Почему это происходит? Есть ли что-то, связанное с тем, как работает javascript, которого я здесь не понимаю?

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Проверьте эти две строки

 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}`;
0 голосов
/ 04 января 2019

viewData.entries.push(jsonData); выдвигает ссылку объекта "jsonData" на массив, а не на копию. Это означает, что когда вы изменяете объект jsonData, ссылка, которая была помещена в массив, также будет изменена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...