DEV Community

kim-jos
kim-jos

Posted on • Edited on

What is the Scope Chain in JS?

What is scope?

Scope is the context in which variables and functions can be accessed. If you can access or use a certain variable or function then it is within its scope.

What is a lexical environment?

The lexical environment is the local memory plus the lexical environment of its parent. These explanations are really confusing so let's use an example to simplify things.

function outer() {
  var a = 10;
  inner();
  function inner() {
    console.log(a); //10
  }
}
outer(); //10
console.log(a); //a is not defined
Enter fullscreen mode Exit fullscreen mode

As you can see the last console.log(a) prints a is not defined because the variable a is not within its scope. However, the console.log(a) that is inside function inner() prints 10 even though variable a is not within the same scope (variable a is in the local memory of function outer not inner). This is possible because variable a is in function inner's lexical environment. We have to understand how the call stack works to see how this is possible.

Let's review the JS execution context. First, before the code even runs JS creates a global execution context. There, it allocates memory to function outer(). Once a function is invoked, JS pushes it into the call stack. In this case, outer was invoked and is pushed in the call stack as you can see in the snapshot below. It goes through the same process and allocates memory to variable a and copies the function inner. Then function inner is pushed into the call stack because it was invoked.

Now, where does the lexical environment come into play here?

For every execution environment, JS first looks in its local memory to see if a variable exists. If it doesn't exist there it goes up to its parent's environment to see if the variable exists there. It continues this process all the way up to the global execution environment and if it doesn't exist there it returns null. This ability to look at its parent's local memory all the way up to the global execution context is the scope chain because it can access all the variables in its parent's local memory.
image

Don't take my word for it. Let's actually run the code to see if it really does what I'm claiming it to do. I put a debugger on line 5 to see the code at that point in time. You can see that I highlighted the scope on the right in yellow and the call stack in orange. In terms of scope it can access local, outer, and global. Where it says closure is the scope of the function outer as you can see in parenthesis the name outer.

You can also see that the call stack has outer, inner, and global execution contexts.

image

Top comments (0)