Lexical Scoping Issue

76 views Asked by At

I am reading the book 'Scope & Closures' in the series 'You Don't Know JS' and I read that functions are hoisted first and variables later. Going through this code snippet:

function foo() {
    var a = 2;
    function bar() {
        console.log( a ); // 2
    }
    bar();
}
foo();

If this is the case, should the function bar() be not hoisted to the top and this code should produces error? because after hoisting, this code should be like this (at least what I understood)

function foo() {
    function bar() {
        console.log( a );
    }
    var a;
    a = 2;
}

This is because function is hoisted to the top and later variables. If this is not the case, please correct me.

2

There are 2 answers

0
T.J. Crowder On BEST ANSWER

They're both hoisted all the way to the top, so a is in scope for bar; it's not that functions are "above" variables. The only time the order comes into play is when the function declaration and variable have the same name, in which case the function declaration wins because when the variable is being hoisted, it's not created if there's already an existing binding with the given name.

"Hoisting" is a convenient shorthand term but it's not literal. What happens when foo is called (leaving out a fair bit of detail to focus on the issues in the question) is:

  1. An execution context is created for the call to foo
  2. An object within that context is created to hold "bindings" for identifiers (like bar and a in your example) for that context's execution
  3. All function declarations are processed and bindings for their identifiers are added to the object (if there are multiple declarations with the same name, the last one wins)
  4. All variable declarations are processed and their identifiers are added to the object if the object doesn't already have bindings for them

That object is then used for handling the bindings in the execution context (e.g., the value associated with a binding is used when a is referenced, and set when a is set, etc.).

0
Arun Redhu On

hoisting is done during the compilation part and compilation of bar function is not done until it is called. So why bar should display error. If you further want to know the details about how javascript is compiled or executed. Here is a nice video https://www.youtube.com/watch?v=QyUFheng6J0