0

I am kind of confused how lexical scoping is being done in JavaScript, for example

function outer(){
    a = 5;
    function inner(){
        console.log(a);
        var a = 10;    //hoisting
    }
    inner();
}
outer();

If we redefine a in line 5, then it will print undefined. Why is that? Why doesn't the interpreter traverse up and check outer.VO even though a can be found in inner.VO, but it is being used before it is defined?

gariepy
  • 3,576
  • 6
  • 21
  • 34
peter
  • 8,333
  • 17
  • 71
  • 94
  • 4
    vars go to the top, so your code is really function inner(){ var a; console.log(a); a=10; } – dandavis Jul 08 '13 at 21:07
  • Because that's exactly what hoisting means: It will not traverse the scope chain further, because the identifier **is already found in the scope of `inner`**, and resolves to the inner `a` variable even if that has not yet been initialised. – Bergi Mar 04 '16 at 04:57

1 Answers1

3

From what I can remember, hoisting causes that inner function to be interpreted as such:

function inner(){
    var a;
    console.log(a);
    a = 10;
}

So when you assign a to 10, it looks up the scopes until it finds the definition for a, which is at the var statement inside the inner function. It sees no need to go outside of that so it acts like the a in the outer function doesn't exist. Also, when var a; is executed, a is set to undefined by default. That's why you're seeing undefined for output.

I will explain this a bit wider Javascript interpreter does the following when it encounter a function (This is known as Execution Context) A- Creation Stage 1- first step it makes an inaccessible object called variable object, it looks like that for your outer function

a: undefined 
inner : pointer to function

2- It defines the scope chain of the function and the value of 'this'

B- Code Execution Stage It executes the code line by line

and if it encountered a call to a function that is not declared yet, it will execute it remember

    inner : pointer to function

If you called inner() before the declaration,it's okay but that doesn't work for anonymous functions

As it's treated like any variable

fn();
var fn = function () {..}

this won't work because its variable object will be like that

fn: undefined 
Shady Atef
  • 2,121
  • 1
  • 22
  • 40
Justin Chmura
  • 1,939
  • 1
  • 15
  • 17