1

I have a for loop

for (var i = 0; i < markers.length; i++) {
    markers[i]["index"] = i;  
}

After click to marker , Always return last item

marker.bindPopup(popup).on('popupopen',function(e){     
   console.log(marker["index"]);
   //return last item
})
Ivar
  • 6,138
  • 12
  • 49
  • 61
Roberto
  • 41
  • 3
  • 1
    You `let` instead of `var`, it might fix it, it it does I'll explain why – Akxe Aug 17 '21 at 10:54
  • 1
    It's very hard to understand (1) what you want to achieve, (2) what the objects in the code snippets contain and (3) what have you tried. "last item" -> which item? from where? "last" as in the last element of the array or "last" according to some other metric? – gbalduzzi Aug 17 '21 at 10:58
  • 2
    Your question lacks sufficient details to know why this is happening. Please provide a [mcve] for us to be able to help you. (If using `let` fixes the problem, it would mean that your loop contains more than you're showing here.) – Ivar Aug 17 '21 at 10:58
  • 1
    I changed it to let and it makes the value correct .Thank you , so the problem is what please ? – Roberto Aug 17 '21 at 11:01
  • 1
    @Akxe you must be a mind reader, good job! – gbalduzzi Aug 17 '21 at 11:02
  • 1
    It means [you have a closure inside of your loop](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example). (Which is not what you're showing here.) – Ivar Aug 17 '21 at 11:04
  • Does this answer your question? [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Akxe Aug 17 '21 at 15:32

1 Answers1

0

Here is an example of what is the underlying problem. It is a problem of "closures". It is a complicated topic that a lot of JS developers don't understand.

function withLet() {
  for (let i = 0; i < 3; i++) {
    const expectedI = i;
    setTimeout(() => {
      console.log('withLet', { expectedI, actualI: i });
    });
  }
}

function withVar() {
  for (var i = 0; i < 3; i++) {
    const expectedI = i;
    setTimeout(() => {
      console.log('withVar', { expectedI, actualI: i });
    });
  }
}

withLet();
withVar();

About why...

The var keywork creates the variable in the scope of the function withVar. If any function inside of the withVar function needs to access the i variable it will get the reference shared between all of the iterations of the loop.

All functions, be it event handlers or simple setTimeout will thus get the reference of the variable after all synchronous code has run.

The let keyword created a new closure, one closure per loop iteration, thus if any function inside the for loop needs to access i, it will get the reference of its own and only i.

for (let i = 0; i < 3; i++) {
  const expectedI = i;
  setTimeout(() => {
    console.log('withLet', { expectedI, actualI: i });
  });
}

console.log(i); // Error! Variable "i" is not defined!
Akxe
  • 9,694
  • 3
  • 36
  • 71
  • Why add yet another answer to a question that has been asked thousands of times on SO already? There is an [excellent duplicate target](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) for it. – Ivar Aug 17 '21 at 13:50
  • Because the people don't know what they are looking for when they search it. They see a (to them) unexplainable error. – Akxe Aug 17 '21 at 14:27
  • Which is why we keep (some) questions as signposts, and mark them as duplicates so all the useful information is in one place. See [Why are some questions marked as duplicate?](https://stackoverflow.com/help/duplicates) Adding yet another answer isn't going to add any value. (In fact, it is only spreading the information, which is what the duplicate system is trying to prevent.) – Ivar Aug 17 '21 at 14:30
  • Why didn't you marked as duplicate then? I would second you! – Akxe Aug 17 '21 at 14:46
  • 1
    Because I already used my close vote as "needs MCVE" and I can't vote twice. The question itself still lacks the actual details to reproduce the problem they have. There isn't a closure in the for-loop they're showing. – Ivar Aug 17 '21 at 14:47