Scope, Scope chain and Lexical Environment in JavaScript

Scope

Scope is the accessibility of variables, functions and objects in some particular part of your code during runtime. In other words, scope is where you can access a specific variable or function in our code.

Scope is directly dependent on lexical environment.

Lexical Environment

Whenever an execution context is created a lexical environment is also created. Lexical environment is the local memory along with the lexical environment of its parent. It means that in a group of nested functions, the inner function will have access to the memory space of its parent function.

Let's see how this works with an example.

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

In the above example, function c() is lexically sitting inside the function a().

lexical-env.jpg

When we run the above program a global execution context(GEC) is created and it is put on to the call stack. It will try to assign values to the variables and functions present in the global space. So it will put function a() in the memory space of global execution context.

When the function a() is invoked, an execution context of that function will be created which is also known as local execution context of that function. Again it will try to assign values to the variables and functions present in the local space of that function. Therefore, variable 'b' and the function c() will be kept in the memory space of its execution context.

Similarly an execution context of function c() will be created and values will be assigned to the variables and functions present if any.

Whenever an execution context is created, we also get a reference to the lexical environment of its parent.

When JavaScript engine encounters the console.log(b) it tries to find b inside the local memory of c(). If it is not present inside the local memory then it will go to the reference of lexical environment and will go to the lexical environment of its parent. Here c's lexical parent is a(), so it will go to the lexical environment of a() and will search for b. It finds b it goes back and will print the value of b.

In case if b is not present in the lexical environment of its parent (i.e. a()). then it will go to its grandparent's lexical environment(i.e. GEC).

If it does not find b in global execution context then it will go to the lexical environment of its parent which points to null which will give the reference error as not defined.

Scope chain

The mechanism of finding the variable among different lexical environments is called as scope chain. It is the chain of all lexical environments and its parent's references.

The JavaScript engine tries to find the variable in the current scope and if it does not find the variable then it goes to the outer scope and continues to do so until it finds the variable or reaches the global scope.