Hoisting LET vs VAR weird things

So I know the difference between LET and VAR is that var keyword/statement declares function scoped variables, while let declares block scoped variables, but when mixed with hoisting mechanism, it turns out that var is limited ONLY to function-scope hardcore.
Is my understanding correct?
Code example:

var x = 100; //or 'let', this line doesn't affect the output.

function hoist() {
   if (false) {
    var x = 200; //this 'x' is INTERRUPTING the variable declaration of the outer scope OR re-declaring it.
  }
  console.log(x);
}

hoist(); //prints out undefined.

VS when let is used even inside blocks “}” of the if statement… in my own words: “X will be declared to the top of the global context, but initialized(/defined), of course, upon that particular function’s call”. Am I correct?
Code modified:

var x = 100; //or 'let', this line doesn't affect the output.

function hoist() {
   if (false) {
    let x = 200;  //modified 'var' into 'let'.
  }
  console.log(x);
}

hoist(); //prints: 100

WoW, ok so I dived so deep (adele is rolling here) which is beyond what juniors out there working in a company rn know, and should perhaps just refer to let over var.

Which also means prior to ES6 (introduction to let and const) CLOSURE was not a thing ?
Since it will cause weird errors as:

function parent() {
    var x = 100;
    function child() {
        if (false) {
            var x = 200;
        }
        console.log(x);
    }
    child()
}
parent(); //prints undefined

Ok, I am at Adele’s concert on Titanic.

My final understanding, simplified:

If a var-clone is declared inside blocks that are nested in a function scope, it will exit the block-scope to fight back the outer/original conflicting-name variable’s value interrupting inside clone’s function scope until their value is diminished (undefined).

No outer-original jokes with var-clones-created-in-nested-blocks-of-a-function-scope . They are so protective!

try this variation, see if that helps you understand, what’s going on

var x = 100; //or 'let', this line doesn't affect the output.

function hoist() {
   if (true) {
    var y = 200; //this 'x' is INTERRUPTING the variable declaration of the outer scope OR re-declaring it.
       console.log(y, '!!');
  }
  console.log(x, y);
}
hoist(); // will print (200, !!) and (100, 200)
var x = 100; //or 'let', this line doesn't affect the output.

function hoist() {
   if (false) {
    var y = 200; //this 'x' is INTERRUPTING the variable declaration of the outer scope OR re-declaring it.
       console.log(y, '!!');
  }
  console.log(x, y);
}
hoist(); // will print 100, and undefined

does it get any better or worse? :grin:

Yep I see that, so that’s why I should always use let to avoid this trouble with its block-scoped nature the y will return 200!! then Reference Error: y is not defined.

btw, there is a difference, between “undefined” and “reference error”!!

if you use "let in this “if block” then you will get an “reference error” but when used “var” you’ll get “undefined” in outside of that “if block” for “false”

just thought of clearing this up, hope this helps even better!!

happy learning :slight_smile:

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.