Hacker News new | ask | show | jobs
by NwtnsMthd 727 days ago
Do you think you could elaborate on why the results differ? I'm somewhat unfamiliar with how JavaScript works.
1 comments

'var' is JavaScript's older variable declaration construct. Variables created this way are live from the beginning of the function that contains them (or globally if there isn't one). So a block with braces (such as you'd use for a for or while loop body) doesn't actually restrict the scope of var `v` below:

    console.log(v); // <-- v is a variable here, we can access its value even though it is only declared below
    // prints 'undefined'
    {
        var v = 1;
        console.log(v); // prints 1
    }
    console.log(v); // prints 1
You used to (and might still) see a workaround to recover more restrictive scoping, known as the "IIFE" (Immediately Evaluated Function Expression): (function () { var v; ... code using v here ... })() creates a function (and thus a more restrictive scope for v to live in) and evaluates it once; this is a sort of poor man's block scoping.

`let` and `const` were created to fill this gap. They have block scope and are special-cased in for loops (well, `let` is; you can't reassign to a `const` variable so nontrivial for loops won't work):

    console.log(l); // <-- throws ReferenceError: l is not defined
    {
        // pretend the console.log line above is commented out, so we can reach this line
        let l = 1;
        console.log(l); // prints 1, as expected
    }
    console.log(l); // throws ReferenceError: l is not defined
    // ^^ l was only in scope for the block above

    
The interaction with `for` is explained well on MDN, including the special casing: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

"More precisely, let declarations are special-cased by for loops..." (followed by a more detailed explanation of why)

See also https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Fun(?) fact: it's not technically true that const can't be used in for loops:

    for (const i = 0; i > 0; ) {
        console.log('this is stupid');
    }

    let ran = false;
    for (const i = 0; !ran; ran = true) {
        console.log('this is also stupid');
    }