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.
-
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
4 Answers
Reset to default 3The 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条)