javascript - forEach loop doesn't update an Object value - Stack Overflow

I'm trying to do a single loop and update an object property with each loop value but something un

I'm trying to do a single loop and update an object property with each loop value but something unexpected happens:

The first console.log prints the day object property updated as expected. The second one, however, which prints the full object, shows the day property with the value of the final forEach value.

Example: data.days = [ 5, 6 ]

First loop prints:

newData.date: 5
{prop1: x, prop2: x...., date: 6}

Second loop prints:

newData.date: 6
{prop1: x, prop2: x...., date: 6}

This is the my code:

data.days.forEach(day => {
    let newData;
    newData = data.data;
    newData.date = day;
    console.log('newData.date: ' + newData.date)
    console.log(newData)
})

I've tried to create the newData variable out of forEach or a for loop instead, but I have the same result.

I'm trying to do a single loop and update an object property with each loop value but something unexpected happens:

The first console.log prints the day object property updated as expected. The second one, however, which prints the full object, shows the day property with the value of the final forEach value.

Example: data.days = [ 5, 6 ]

First loop prints:

newData.date: 5
{prop1: x, prop2: x...., date: 6}

Second loop prints:

newData.date: 6
{prop1: x, prop2: x...., date: 6}

This is the my code:

data.days.forEach(day => {
    let newData;
    newData = data.data;
    newData.date = day;
    console.log('newData.date: ' + newData.date)
    console.log(newData)
})

I've tried to create the newData variable out of forEach or a for loop instead, but I have the same result.

Share Improve this question edited May 23, 2019 at 15:14 Ian 6,1646 gold badges45 silver badges76 bronze badges asked May 23, 2019 at 15:01 Ken RamirezKen Ramirez 3357 silver badges17 bronze badges 4
  • 1 data.days = { 5, 6 } is invalid syntax – Maheer Ali Commented May 23, 2019 at 15:03
  • As Maheer Ali tolds you : forEach works on Arrays and data.days is ... – PhilMaGeo Commented May 23, 2019 at 15:05
  • newData = data.data is copy by reference, you're actually assigning the same object on every loop. That's why you always get the last value in the final loop... – IronGeek Commented May 23, 2019 at 15:18
  • data.days is declared as an empty array and the values are pushed or spliced as i need before to call the loop. In fact, it's printing the correct value in each loop as you can see in the first console.log – Ken Ramirez Commented May 23, 2019 at 15:31
Add a ment  | 

4 Answers 4

Reset to default 3

The issue you are seeing is caused by the fact that the browser console, in an attempt to be very helpful, is not logging a string when you log an object. Instead, it's logging a live view of that object. Therefore, if you log the object and then update it, you will see the updated version in the console. However, when you log the property of the object, the console logs it as a static string.

You can see this here:

The string is just logged as a static string, but the object is treated specially, with syntax highlighting and expanding property views and such.

Here's an example where we log the static stringified version of the object instead as well as the dynamic reference to the object:

let days = [5, 6];
let newData = {};

days.forEach(day => {
    newData.date = day;
    console.log('newData.date: ' + newData.date);
    console.log(JSON.stringify(newData));
    console.log(newData);
});

This yields:

Your issue is here:

...
let newData;
newData = data.data;
...

You're not creating a new object with newData variable, instead you're just referencing the same data.data object into it on each iteration. This is why the final newData value will always be what is sets on the last loop iteration.

If want a new distinct object for each loop, you need to (deep) clone/ copy the data.data instead of just referencing it:

var data = {};
data.data = { prop1: 'x', prop2: 'x' };
data.days = [ 5, 6 ];

data.days.forEach(day => {
    let newData;
    newData = Object.assign({}, data.data); 
    newData.date = day;
    console.log('newData.date: ' + newData.date)
    console.log(newData)
});

Note: Object.assign does shallow copy of an object, you need to resort to something else if need to deep copy the object.

Objects don't have forEach method (it's mainly for Arrays) but you can iterate on their properties with for (let prop in object).

In your example:

for (let day in data.days) {
    // Do your stuff
}

https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Statements/for...in

According to ECMAScript documentation, a link

at 22.1.3.12 Array.prototype.forEach ( callbackfn [ , thisArg ] )

callbackfn should be a function that accepts three arguments. forEach calls callbackfn once for each element present in the array, in ascending order. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744192935a4562518.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信