javascript - Explanation of `let` and block scoping with for loops -


i understand let prevents duplicate declarations nice.

let x; let x; // error! 

variables declared let can used in closures can expected

let = 100; settimeout(function () { console.log(i) }, i); // '100' after 100 ms 

what have bit of difficulty grasping how let applies loops. seems specific for loops. consider classic problem:

// prints '10' 10 times (var = 0; < 10; i++) { process.nexttick(_ => console.log(i)) } // prints '0' through '9' (let = 0; < 10; i++) { process.nexttick(_ => console.log(i)) } 

why using let in context work? in imagination though 1 block visible, for creates separate block each iteration , let declaration done inside of block ... there 1 let declaration initialize value. syntactic sugar es6? how working?

i understand differences between var , let , have illustrated them above. i'm particularly interested in understanding why different declarations result in different output using for loop.

is syntactic sugar es6?

no, it's more syntactic sugar. gory details buried in §13.6.3.9 createperiterationenvironment.

how working?

if use let keyword in for statement, check names bind , then

  • create new lexical environment names a) initialiser expression b) each iteration (previosly evaluating increment expression)
  • copy values variables names 1 next environment

your loop statement for (var = 0; < 10; i++) { process.nexttick(_ => console.log(i)) } desugars simple

// omitting braces when don't introduce block var i; = 0; if (i < 10)     process.nexttick(_ => console.log(i))     i++;     if (i < 10)         process.nexttick(_ => console.log(i))         i++;         … 

while for (let = 0; < 10; i++) { process.nexttick(_ => console.log(i)) } "desugar" more complicated

// using braces explicitly denote block scopes, // using indentation control flow { let i;   = 0;   __status = {i}; } { let {i} = __status;   if (i < 10)       process.nexttick(_ => console.log(i))       __status = {i}; }   { let {i} = __status;       i++;       if (i < 10)           process.nexttick(_ => console.log(i))           __status = {i};     }   { let {i} = __status;           i++;           … 

Comments