JavaScript scope chain

Variable environment

In javascript variable belongs to a execution context. What does that mean? Let's look at the code below. function b(){ var test; } function a(){ var test = 2; b(); } var test; test = 1; a();
Let us go through each line of the code and analyze. During execution, javascript global context which is already created by browser and globally available will be assigned. That global context will get the variable test and value as undefined.
Next, same variable test now get value 1 and in next line function a() will be called.
As we know any function call will create its own execution context, so function a() will get its execution context on top of global execution context.
Now function a() got it's own variable named as test which is having value 2.

Next function b() getting called from within function a(). So function b()'s execution context will be created on top of function a() and memory space for variable will be allocated for that execution context. In that memory space function b()'s variable will reside which is test, named it same. In this case test will get the value, which javascript automatically assigns to any undefined variable i,e undefined(which is a keyword value).

Notice test variable is unique for each of the execution context or in other-way to say for each function.
Cinque Terre

scope chain

scope chain determines the value of a variable based on the lexical context of that function.
Lets explain that. function b(){ var test; console.log(test) } function a(){ var test = 2; b(); console.log(test) } var test; console.log(test) test = 1; console.log(test) a(); console.log(test) Easy enough to say the output in the console for test variable. As each variable got created within function so it got allocated with memory space in that function's execution context.
undefined
1
undefined
2
1

Now remove variable declaration within function b(), so what would be the out put? function b(){ console.log(test) } function a(){ var test = 2; b(); console.log(test) } var test; console.log(test) test = 1; console.log(test) a(); console.log(test)
undefined
1
1
2
1
Why so? When javascript start executing code line by line it tries to find any undeclared variable within that execution context, in this case it tries finding test within function b(), but it didn't get there.
So what it does next is it looks at the outer reference of that function to get the variable.

Outer reference

Outer reference of any function depends on how the function is written lexically or where physically the function situated. In our case function b(), physically situates in the context of global reference, just like var test. It is attached with the global context lexically. Don't get confused with the execution stack which is how function would be invoked not where the function's outer reference pointing to. So in our case function b() and function a() both has outer reference to the global context, because that is where they are lexically situated. Cinque Terre Now lets make little more change to the same code. function a(){ var test = 2; b(); console.log(test) function b(){ console.log(test) } } var test; console.log(test) test = 1; console.log(test) a(); console.log(test)
undefined
1
2
2
1

Did you see that ?

As soon we moved the function function b() inside function a() the function b() lexically now no more with the global object context but with function a() object context. So when javascript engine during execution didn't find the variable test it falls back to the outer reference and in this case it's function a() it find the variable test there and get the values from function a() execution context which is 2 in this case. Cinque Terre Let's make further more change to the sample code. function a(){ b(); console.log(test) function b(){ console.log(test) } } var test; console.log(test) test = 1; console.log(test) a(); console.log(test)
undefined
1
1
1
1
Now we can see neither function a() nor function b() has the variable test declared. So when function b() tries to get the variable test it doesn't find there so it falls back to it's outer reference which is function a() because that's where it lexically situated.But in the above case it doesn't find the variable test there too. So where should it go? it follows the outer chain of function a()which is global execution context and tries to access variable test . It finds the variable in the global context and access its value from there. Cinque Terre This phenomenon of referencing outer reference in a sequential manner is referred to as scope chain.

what happens now ?

function a(){ console.log(test) function b(){ console.log(test) } b(); } var test; b(); a(); Look in this scenario when javascript engine start reading the code each line by line it finds the function call b() now interpreter still on the context of global object and global object context's lexical environment is global. However function b() not situated lexically not within global context, but it's situated lexically within function a(). From global it has no access to function b(), so interpreter will end up throwing error.
Uncaught ReferenceError: b is not defined
Back Next