0

I am trying learn Node.js. I dynamically built an array, I used push to put a function in each element.

var arr=[];
for(var x=0;x<8;x++)
    arr.push(function(){ console.log(x); });

I 'think' I am pushing a anonymous function into the array that when called should print to the console the value of 'x' during the iteration. IE first iteration x==0, second x==1 and so forth until 8th iteration, this means the largest number pushed should be 7. I then attempt to print each element to the console using a forEach loop

arr.forEach(function(ar)
     { 
       ar(); 
     });

I 'think' this loop will iterate from element [0] to the end of the array. In each iteration I call the function for that element. ar(); I thought I would get the numbers 0,1,2,3... 7 printed to the console, each number on a new line.

For each iteration the number 8 is printed to a new line of the console.

The number 8 shouldn't it be 7? Why is only 8 being printed? What is happening?

If I do not push a function into the array but push x and use a forEach loop to console.log the correct numbers are printed.

Wyght
  • 57
  • 6
  • 2
    Possible duplicate of [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – haim770 Oct 05 '16 at 07:32
  • 1
    Change `var x` to `let x` – haim770 Oct 05 '16 at 07:33

1 Answers1

1

This happens because your callback function cann't find "x" variable inside of its scope (LexicalEnvironment) and searches for it outside, in the global scope. And in global scope your "x" value holds a last value of your loop, which is 8.

So each time in your second loop it takes the same value from global scope. Try to change your code like this:

 arr.push((function(x){ console.log(x); })(x));

What we do here is we pass a new value of each iteration as an argument to the function (save it to function's LexicalEnvironment) and immediately executed it (check IIFE).

Learn about closures in Javascript and how they work.

Andrii
  • 329
  • 2
  • 8
  • Okay, your code caused the forEach to run correctly and display correct value for 'x'. Once the end of array happened an error was thrown `TypeError: ar is not a function`. Your answer helped me immensely, I did not know about closures, I have to learn this. I did not capture what was happening in my push either. IE the var x 'not' the value of the var x was pushed. I will read what you have suggested and try later thanks – Wyght Oct 05 '16 at 16:56