Reputation: 2646
I'd like someone - preferably Jon Skeet but I'll accept answers from mere mortals - to explain the following basic JavaScript scenario to me. I have a function similar to the following:
myFunction()
{
var row;
for (var i = 0; i < collectionView.itemsAdded.length; i++)
{
row = this.collectionView.itemsAdded[i];
}
for (var i = 0; i < collectionView.itemsAdded.length; i++)
{
// this always logs as the last value it was given from the first loop. I expected it to give me the same variety of values it gave me in the first loop.
row.property1 = true;
}
}
Unexpectedly, the second use of row
always results in whatever the final value the first for loop gave it. i.e. if collectionView.itemsAdded.length
is 45, row
will log as 44 (bc zero index) and stay 44 on every iteration of the second loop
.
I falsely expected that calling row
in the second for loop
would be enough to give me the same results row
gave me in the first for loop
. I thought that for each iteration of the second loop
, row
would log as a different item - instead, it logs every time as this.collectionView.itemsAdded[44]
which it got from the first loop.
In my head, I get it. But can anyone explain further what's happening here? If row is supposedly this.collectionView.itemsAdded[i]
- why isn't it transferable to another loop? Why must I again declare row = this.collectionView.itemsAdded[i]
in the second for loop
if I want the same values?
Upvotes: 0
Views: 76
Reputation: 7632
myFunction()
{
var row;
for (var i = 0; i < collectionView.itemsAdded.length; i++)
{
// this row will assign a new value to row in each iteration
row = this.collectionView.itemsAdded[i];
}
// first run: i = 0 ||| row = this.collectionView.itemsAdded[0]
// second run: i = 1 ||| row = this.collectionView.itemsAdded[1]
//...
// last run: i = 44 ||| row = this.collectionView.itemsAdded[44]
// this loop is not executing until the first loop is finished this is why in
// the first iteration of this loop the value is the last value assign to
// row in the first loop
for (var i = 0; i < collectionView.itemsAdded.length; i++)
{
// this row is just using the last assign value to row (from the last
// iteration in the first loop
row.property1 = true;
}
// first run: i = 0 ||| row = this.collectionView.itemsAdded[44]
//...
// on each iteration you'r just using the last value assign to row from the
// first loop
//...
// last run: i = 44 ||| row is still = this.collectionView.itemsAdded[44]
}
It's very simple. The first loop is assigning the row in each iteration of i
leaving row assigned with the last i
as the last row. In the second loop you're using the saved row
variable assigned in the last iteration of the first loop which is the last row.
Upvotes: 1
Reputation: 5301
row
is just holding a reference to an object. In first loop, it keeps on changing. After the loop ends, the value of row
is not updated. So, in the second loop, the operations are done on the same object i.e. the last value that was assigned to row.
Upvotes: 2
Reputation: 1793
Row is not an array. In the first loop, row is assigned in every iteration which is why it equals this.collectionView.itemsAdded[44]; at the end.
In the second loop, what you are doing is assigning :
this.collectionView.itemsAdded[44].property1 = true;
If you want to assign every item of your list to true, row should be an array and in the frst loop you would need to push every item like this:
row.push(this.collectionView.itemsAdded[i]);
Upvotes: 1
Reputation: 1004
You need to declare row as an array instead of object. Object wil override the value when next value with same key comes, but array with add it in queue.
On the first iteration please push the required value to row
let row=[]
row.push()
Upvotes: 0