-2
// i declared in (), not in {}
for(let i = 0; i < 5; i++){
  console.log("for:" + i);
}

console.log(i); // error

Why did it assume that variable i belongs to loop scope if it was declared outside the loop's body brackets?

I found this:

"Variables declared with let are local to the statement"

Source

Ok, but why is it so?

devope
  • 127
  • 11
  • 1
    Because that's how the language defines what `let` does in a `for` loop. – Pointy Apr 17 '22 at 17:10
  • 1
    The declaration of `i` is within the `for` statement. – Andrew Morton Apr 17 '22 at 17:10
  • Andrew, so does statement define a scope in JS? I thought that scope is defined by curly braces. – devope Apr 17 '22 at 17:15
  • 1
    It's kind-of a weird wrinkle in the way the language works. There are really *two* scopes involved: the scope of the `for` loop header, and the scope of the loop body. It's invisible to the programmer, and it behaves as if it's the same `i` in the header and the body. – Pointy Apr 17 '22 at 17:57
  • Pointy, finally! Thanks a lot. Can you please provide a link with a detailed description of this interesting behavior? – devope Apr 17 '22 at 18:09
  • @KirillDevope MDN web docs explains it: [for](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for). – Andrew Morton Apr 18 '22 at 13:00
  • @andrew-morton it doesn't. – devope Apr 20 '22 at 17:19
  • @KirillDevope You could read the ECMAScript Language Specification linked to on the page I linked to, depending on what you consider to suffice for a description. `var` was too loose and let variables leak out all over the place, so `let` was added to keep them to a scope. – Andrew Morton Apr 20 '22 at 18:25

2 Answers2

1

The main issue here is the type of variable you're saving the index value for. We have two solutions to solve this problem. First:

let i = 0; /* using let out of for loop */
for(;i < 5; i++){
  console.log("for:" + i);
}

console.log(i); // no error

Second:


for(var i = 0; i < 5; i++){ /* Using var */
  console.log("for:" + i);
}

console.log(i); // no error
Wraithdev3
  • 41
  • 6
  • I think it's more that those are two ways to create a problem of the variable having more scope than needed in most cases ;) – Andrew Morton Apr 17 '22 at 17:14
  • Actually, the error is not a problem for me. I referred to the error here just to show that the scope of the ```i``` is "obviously" not global – devope Apr 17 '22 at 17:14
  • Andrew, you're right. And if that create a problem. That can be solve with `delete i;` – Wraithdev3 Apr 17 '22 at 17:16
  • Kirill, Thats become problem, beacause v8 engine thinks `i` part of loop and this cannot be global. I when tried run original code on nodejs i get : `for:0 for:1 for:2 for:3 for:4 for:0 for:1 for:2 for:3 for:4` in console. After that code gives error. Thats mean this code cause bug in nodejs. – Wraithdev3 Apr 17 '22 at 17:19
  • I just don't understand why if you declare ```i``` inside of ```for()``` becomes declared in the local scope of loop. – devope Apr 17 '22 at 17:26
1

One of the main difference between let and var is that let allows you to declare variables that are limited to the scope of a block statement:

{
  let a = 10;
}

console.log(a); // ReferenceError: a is not defined

at the same time var would work fine with that scenario.

Getting back to your example, the same is happening with for loop. So one of the solution, if you want to have an access to counter - is to create external variable and use it in your loop. You can also achieve the same result with while:

let counter = 0;

while(counter < 5) {
  // do stuff
  counter++;
} 

console.log(counter); // 5
James Jr.
  • 163
  • 6
  • Sorry, but this is not what I looking for. I understand how local scope works inside curly braces. I just don't understand why variable declared inside `for()` not `{}` is assumed like a local variable of the loop. – devope Apr 17 '22 at 17:24
  • https://stackoverflow.com/questions/18465211/javascript-loop-variable-scope – James Jr. Apr 17 '22 at 17:26
  • Sergey, it doesn't explain the reason I'm looking for. – devope Apr 17 '22 at 17:56