Execution Context in JavaScript
Understand how JavaScript code executes behind the scenes with Execution Contexts, the fundamental concept that powers JavaScript's runtime behavior.
🧠 What is Execution Context?
An Execution Context is an abstract concept that holds information about the environment in which JavaScript code is executed. Every time code runs in JavaScript, it runs inside an execution context.
- Global Execution Context - Created when script first runs
- Function Execution Context - Created when a function is invoked
- Eval Execution Context - Created inside eval() function
💡 Key Insight
JavaScript is single-threaded, meaning only one execution context runs at a time. This is managed by the Call Stack.
Components of Execution Context:
- Variable Environment
- Lexical Environment
- This Binding
⚙️ How Execution Context Works
Two Phase Process
1. Creation Phase
- Create Variable Object (Activation Object for functions)
- Setup Scope Chain
- Determine
thisvalue - Hoisting occurs in this phase
2. Execution Phase
- Code is executed line by line
- Variables are assigned values
- Functions are called
Lifecycle of Execution Context
- Creation: Context is created and pushed to call stack
- Execution: Code runs and modifies variables
- Completion: Function returns or script ends
- Cleanup: Context is popped from call stack
🔄 Basic Execution Context Example
Let's trace through a simple example to see execution contexts in action:
Execution Flow:
- Global Execution Context created and executed
- When
outerFunction()is called, new execution context is created - When
innerFunction()is called, another context is created - Each context maintains its own variable environment
📊 Creation vs Execution Phase
Understanding hoisting through the lens of execution context phases:
⚠️ Hoisting Behavior:
var declarations are hoisted and initialized with undefined
Function declarations are fully hoistedlet and const are hoisted but not initialized (Temporal Dead Zone)
🔍 Memory Allocation:
During creation phase, memory is allocated for all variables and functions
This is why we can access them before they appear in code
🔗 Lexical Environment
Every execution context has a Lexical Environment which consists of:
Lexical Environment Components:
| Component | Description |
|---|---|
| Environment Record | Stores all variable and function declarations |
| Reference to Outer Environment | Link to parent lexical environment (scope chain) |
| This Binding | Reference to this value |
🎮 Interactive Practice
Trace through this practical example to see execution contexts in a real-world scenario:
💪 Challenge:
Try these modifications:
- Add another level of nesting with a
superBonusRoundfunction - Create a counter that tracks how many times
playRoundis called - Add error handling for negative points
- Experiment with different variable declarations (
varvsletvsconst)
📚 Key Takeaways
- Every function call creates a new execution context
- Contexts are managed in a LIFO stack (Call Stack)
- Each context has its own variable environment
- Lexical scope determines variable accessibility
- Creation phase sets up memory for variables and functions
- Execution phase runs the actual code
- Context is destroyed after execution completes
- Understanding this helps debug scope-related issues