shahzaibkhalid
shahzaibkhalid

Reputation: 127

Lexical Scoping Issue

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.

Upvotes: 0

Views: 66

Answers (2)

Arun Redhu
Arun Redhu

Reputation: 1579

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

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074445

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.).

Upvotes: 1

Related Questions