Execution Context is one of the most basic concepts in JS. Let me put it this way.
Everything in JS happens inside the Execution Context.
Let us understand this with the help of an example. The code shown below finds square of the given number.
When we run a JS program, an Execution context is created. There are two phases involved in this process. First phase is called the Memory Creation phase and the second phase is called the Code Execution phase.
In the Memory Creation phase, JS parses the program and looks for variables and function definitions. In case of variables a special keyword called undefined is assigned and in case of functions, JS stores copy of the whole function definition. (check out the diagram).
Note: undefined is not a value. Its a special keyword used in JS to indicate that a variable is not defined or assigned any value.
The second phase is the Code Execution phase. In this phase, JS starts from the beginning and goes in synchronous manner (one line at a time).
At line 1, ‘n’ has a value set to 10 so JS removes the keyword undefined and sets the value to 10. Now the control goes to the next code block. Since this is a function definition, there is no code execution happening here so JS skips the function definition and moves control to line number 8. As soon as JS encounters a function invocation [ square(5) ], it creates a new Execution Context as shown below.
Now the whole process of Execution Context repeats for that function call. Lets see how the execution of the function block happens.
In the Memory Creation phase, we will have two variables, ‘number’ which is your function parameter and ‘ans’ which is the local variable. Both will have value set to ‘undefined’. In the second phase of this current Execution Context, JS starts from the first line of this function declaration. Since we are passing 5 as an argument in the function call, 5 is assigned as the value to the variable number. Now the control goes to the next line.
On the next line, JS executes [ number * number ] part of the line and the result of this operation (which is 25) is stored in the variable ‘ans’. Now the next line has a keyword ‘return’. As soon as JS encounters ‘return’ keyword, it moves control back to the parent Execution Context. Since we are returning the value of ‘ans’, the value 25 is returned and stored in the variable ‘squareOf5’. Now remember this.
When the control moves back to the place where the function call was made, the newly created Execution Context is deleted.
Check out the diagram below.
Now the control goes to the next line which is again a function call and whole process of Execution Context repeats again.
This happens through something called as a Call Stack or Execution Stack. It’s like a regular stack but mainly used for keeping track of Execution Contexts.
When the JS engine first encounters the script, it creates a Global Execution Context (GEC) and is pushed on the Call Stack. During the code execution part of GEC, whenever JS engine encounters a function call, it creates a new Execution Context and pushes it to the Call Stack.
The engine executes the function whose execution context is at the top of the stack. When this function is complete, its execution stack is popped off from the stack, and the process continues for the rest of the script.
I hope now you have got a good understanding of Execution Context now. If I have to explain the importance of Execution Context in simple language, I can say that Execution Context is the heart of JS.
Let me also mention that I have not gone into too much of depth but there are a lot of concepts which can be covered.