In-memory Scope/Execution Context and Lexical Scope in JavaScript [Beginner]
Gaurav Kumar Singh
Software Engineer | Mentor | Teacher| JavaScript Pro | React Pro | Node Pro | Databases Expert | xQL expert | Python | Java | K8s | AWS | Bigdata | ES | AI-ML
Introduction:
The example that I am showing here can be executed and seen in the Google Chrome browser's dev tool . I have created scope.js file here is the code.
You can run javascript in using online compiler or in chrome dev tool or via nodejs check this post.
We are using randomText function in scope.js to generate random string of give length(len).
Lexical Scope:
It is the actual order of written code where you can refer to a variable without getting access error.
Not all curly braces are meant for scoping in JavaScript. So follow it carefully. e.g if statement, for/while loop etc does not create new scopes.
A new lexical scope is created every time you type a function definition but the access rule for the new inner lexical scope will be different.
Although you can access variables of broader lexical scope inside the inner lexical scope (along with the variables that is defined inside of inner lexical scope), the variables of inner lexical scope can’t be accessed from outer lexical scope. In other word, variables declared outside of a function are global variables and are visible everywhere in a JavaScript program. Variables declared inside a function have function scope and are visible only to code that appears inside that function.
Fundamental rule of lexical scoping:
Functions are executed using the variable scope that was in effect when they were defined, not the variable scope that is in effect when they are invoked.?
[We will see this later in closures also to make it more clear, so don’t worry]
Here in scope.js, we have organization and appDetails variable in outer lexical scope i.e global scope [the outermost scope]. We have name variable inside appDetails function which is inside inner lexical scope.
The good thing about lexical scope is you can tell just by looking at the code where a variable is visible inside a block of code whereas actual visibility should be checked at runtime.
In-Memory Scope/Execution Context:
Execution context tells which variable a program has access to at different point during execution. In contrast to lexical scope, in-memory scope/execution context are built as the code runs. Let’s see it step by step.
Step 1: When a program run, it builds storage to hold variables and its values. These in-memory structures are called Execution Context.
In-memory diagram (before appDetails invocation): This is the in-memory diagram for the scope.js code [global context].
The appDetails variable will just have a reference to a function object.
Step 2: Now you can see the log in console. You can execute the appDetails function by invoking it as shown below:
Once you invoke a function, new execution context is created inside the context [global here] where it was defined. New context is shown as red block here. We will have function object stored in appVersion variable .New context is shown as red block as described above.
Since each new run of a function is supposed to operate in complete isolation from all the previous runs, if you execute appDetails once again, a new context will be created.
领英推荐
In-memory Diagram (After 1st appDetails invocation):
Step 3: Now you can see the log in console. You can execute appDetails from console in chrome as shown below:
Check line 18 and 20 where we are invoking the function appVersion twice.
Once you invoke appDetails function, new execution context is created and we will have function object stored in appVersion variable as shown in the above diagram.
When we encounter appVersion function invocation at line 18 & line 20 and?another two(one for each invocation) new contexts are created?(as we know from above that each function invocation will create new context) which is shown as green block this time.
In-memory Diagram (After 2nd appDetails invocation):
Now if you invoke appDetails function once again(as shown in my console) , a whole new set of red context will be created with its own green context for two appVersion invocation.
As stated in the beginning, “Functions are executed using the variable scope that was in effect when they were defined, not the variable scope that is in effect when they are invoked.”
Console log
Let's explain this with in-memory diagram. Here appDetails function is defined and variable organization has value “v962x1” [the variable scope in effect is global scope], so when we are invoking appDetails it used the variable organization value as “v962x1” for both the invocations. Check the console where it logs same value for organization.
Let's see the inner function appVersion invocation to make it more clear, when we are invoking appDetails for the first time, it defines appVersion function?and variable name has value “4aue” [the variable scope in effect is the function scope of appDetails], so when we are invoking appVersion at line 18 & 20 ,it used the variable name value as “4aue” for both the invocations.
Log output:
Line 18 :
{ organization: 'v962x1', name: '4aue', version: 'u7' }
Line 20 :
{ organization: 'v962x1', name: '4aue', version: 'kq' }
Similarly when we invoked appDetails 2nd time, appVersion was defined inside appDetails function scope and the variable name was having value “ba59”. Hence the log output is as below:
Log output:
Line 18 :
{ organization: 'v962x1', name: 'ba59', version: 'kw' }
Line 20 :
{ organization: 'v962x1', name: 'ba59', version: 'sk' }
These concepts are very important to have clear understanding on closures in JavaScript. You can check my other articles on Closures as well.
You can refer Java Script - The Definite Guide and google for more info.Thanks to Udacity for Object Oriented Java Script Course.
Happy Learning....?????????Gaurav Singh