0

I thought I understood the "closure" behaviour of Javascript, and to prevent the most complex problem of this I usually use "let" instead of "var" in all my code. But it seems it is not enough in this case.

I defined a variable in a for loop (called i here for more conveniance). In my loop, I call a function, which has not any parameters, defined somewhere outside the loop, which use this very variable. But it seems that it cannot reach the value of i, even if it is present in the loop scope.

I know that if I defined the variable i outside the loop, or if I remove let in the for line, it would solve my problem. The question is : why does not my function know the value of i?

function printiValue()
{
    alert(i);
}

let table = [1,2,3];
for (let i of table)
{
    printiValue();
}
Flunec
  • 17
  • 5

4 Answers4

0

Because let is just block wide.

You have to declare your variable i before the loop in this case but a forEach loop would be better.

Saeed Zhiany
  • 2,051
  • 9
  • 30
  • 41
D4NT3
  • 141
  • 7
0

You should read this scope.

To make your code work try this:

function printiValue(param)
{
    alert(param);
}

let table = [1,2,3];
for (let i of table)
{
    printiValue(i);
}
Facundo Petre
  • 281
  • 2
  • 5
0

The definition of "let" itself should be clear enough:

"let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope."

Given that definition, the let i in your for loop means its scope is within that for loop, but not within functions called within that loop, unless they are passed it as a parameter.

Run this if you don't believe/understand:

function b() {
  console.log(typeof i);
}

function a() {
    let i = 10;
    b();
}

a();

https://codepen.io/anon/pen/EeVPPB

Chris Cousins
  • 1,862
  • 8
  • 15
  • But does not a function have access to variables defined in the block where it is used? – Flunec Aug 23 '18 at 17:07
  • @Flunec No, it has access to variables defined in the block where it is defined, not where it is used. `alert(i);` is lexically outside the for loop so `i` is not in scope. – Paul Aug 23 '18 at 17:11
0

Your function is declared outside the scope of your for loop, so it has no access to the i value You're also using a for of loop, which is for an object, not an array, you should use a regular for loop. You can either

declare a variable and increment it in the loop

let i = 0;
function printiValue()
{
    alert(i);
}

let table = [1,2,3];
for (let j = 0; j < table.length; j++)
{
    printiValue();
    i++;
}

or pass in i as a parameter:

function printiValue(i)
{
    alert(i);
}

let table = [1,2,3];
for (let i = 0; i < table.length; i++)
{
    printiValue(i);
}

Hope that helps!

CascadiaJS
  • 2,320
  • 2
  • 26
  • 46