0

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?

3
  • Why can't you move the code which is in the second for loop into the first one? Commented Jul 23, 2019 at 17:57
  • This is just a conceptual question. In the real function, one loop occurs before an observable returns a value, the other loop occurs after the value is returned :) Commented Jul 23, 2019 at 17:59
  • You can use map method of array on collectionView.itemsAdded.length to form a different array and use that in the second for loop Commented Jul 23, 2019 at 18:03

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I see. So the way JavaScript works is that this reference is just pointing to the objects location in memory. In the second loop, I expected the compiler to be all like oh! this.collectionView.itemsAdded[i].property1 = true!. But instead it was all like oh, that last object we referenced.property1 = true!. It still makes my head hurt a little but I think I just need more research on basics like references vs values, etc etc
1

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]);

Comments

1
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.

Comments

0

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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.