0

My question is simple if I have a for loop and I had a function inside it, how many times will the function execute.

eg:

for(i=0;i<3;i++){
   console.log(i);
   (function(i){
      console.log(i)
   })
}

If anyone has the answer can you please explain to me why? Thanks in advance.

What about this case:

for (k=0; k<5;k++) {
$( '#a_' + k ).on('click', function() {
console.log("Clicking on a_" + k)
});
}

so when if I pass id as a_1, what will be the console print.

user12551649
  • 366
  • 5
  • 20
  • 0,1,2 After that "i" is not less than 3 anymore; if the function is changing the value of "i", then only you know. – CrossRoads Mar 16 '20 at 19:41
  • As many times as the loop executes. – VLAZ Mar 16 '20 at 19:42
  • @VLAZ I don't think so when executed in the console the function only executed at the end of 0,1,2 – user12551649 Mar 16 '20 at 19:43
  • 2
    You never *execute* the `(function(i){ console.log(i) })` it's just a function expression that defines an anonymous function. However, if you did, then it'd be executed once per loop. – VLAZ Mar 16 '20 at 19:45
  • oh okay, so my function will execute as many times as the loop iterates. – user12551649 Mar 16 '20 at 19:46
  • 1
    If you execute it, then yes. – VLAZ Mar 16 '20 at 19:46
  • lemme update my question stay with me. – user12551649 Mar 16 '20 at 19:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/209725/discussion-between-user12551649-and-vlaz). – user12551649 Mar 16 '20 at 19:50
  • For your second question, it depends on if you use a `var` or a `let` – Keith Mar 16 '20 at 19:52
  • I read this whole discussion but I still don't understand as of why would my code print out value as a_5 even thou the condition is matched at a_1 – user12551649 Mar 16 '20 at 19:52
  • 1
    Because by the time the click handler runs “k” will be 5, in other words, the value that causes the loop to exit. – Dave Newton Mar 16 '20 at 19:54
  • 1
    @user12551649 The first thing you **must** understand is that adding a click handler, by using `button.on('click', some_function)`, the function is **not** executed immediately. It gets executed when you click the button, and uses the current value of `k` when that happens. If `k` was changed between the time you added the click function and the time you clicked the button, the click function uses the *new* value, not the *old* value. When you write a loop using `k=0`, it declares one single global variable, and then changes that same variable each iteration - it will be `5` after the loop. – Klaycon Mar 16 '20 at 19:58
  • Then all click handlers refer to that one `k` variable, whose value is now `5`. – Klaycon Mar 16 '20 at 19:59
  • @Klaycon But it also depends on scope, if the op uses `let` it will print `0,1,2,3,4` but if it's a `var`, it will print `5,5,5,5,5`. – Keith Mar 16 '20 at 20:02
  • Yeah cuz then let won't be global and only have block scope, whereas var variables have global scope – user12551649 Mar 16 '20 at 20:03
  • 1
    @Keith Right, I forgot to specify that too. The goal is to make a different `k` in each iteration (using `let`) rather than reusing the same one (`var` or globals). You can also ensure you capture a different variable using an IIFE if needed. @user12551649 `var` variables have function scope, not global – Klaycon Mar 16 '20 at 20:04

2 Answers2

2

The anonymous function inside the for loop won't execute at all. It would have to be an immediately invoked function expression to get executed.

for(i=0;i<3;i++){
   console.log(i);
   (function(i){
      console.log(i)
   })(i); // pass (i) as argument to execute
}

What you had previously will never execute:

for(i=0;i<3;i++){
   console.log(i);
   (function(i){
      // will never execute because this is function is never invoked
      console.log(i)
   })
}
0

In the first code snippet, the function runs 0 times. You have a function expression, but you never call it. To call it you need to add (<argument>) after the expression.

for(i=0;i<3;i++){
   console.log(i);
   (function(i){
      console.log(i+10)
   })(i)
}

In the second code snippet, all the buttons will log Clicking on a_5. Closures contain a reference to the variable, not a snapshot of its value when they were created. All the closures refer to the same k variable, and at the end of the loop it will be set to 5. So they all concatenate 5 to the log message.

See Javascript infamous Loop issue? and JavaScript closure inside loops – simple practical example for a detailed explanation and solutions.

Barmar
  • 741,623
  • 53
  • 500
  • 612