Javascript Execution Context
Overview
- Execution Context
- Call Stack
- Variable Environment
- Scope Chain
Execution Context
-
The execution context is used to track the runtime code of the javascript engine
-
Global Execution Context is created at the start
- Creation Phase:
- Creates a global object (global in node, window in browser)
- Creates an object called this
- Setup memory space for variables and functions
- Assign variable declarations a default value of "undefined" while placing any function declarations in memory
- Execution Phase:
- Executes each line
- Creation Phase:
-
Function Execution Context
- Creation Phase:
- Creates an arguments object
- Creates an object called this
- Set up a memory space for variables and functions
- Assign variable declarations a default value of "undefined" while placing any function declarations in memory
- Execution Phase:
- Executes each line
- Creation Phase:
-
Hoisting
- Variables and functions allocated a space in memory
- var declarations are assigned default value of undefined
console.log("Before: ", x); // "undefined"
var x = 5;
console.log("After: ", x); // 5
fooBar(); // "Log from fooBar"
function fooBar() {
console.log("Log from fooBar");
}
testFunc() // referenceError
console.log("Value of testFunc before declaration: ", testFunc); // undefined
// Function Expression, testFunc is assigned undefined in creation phase
var testFunc = function () {
console.log("testFunc Call");
};
testFunc(); // "testFunc Call"
Call Stack / Execution Stack
- Call stack keeps track of the function calls
- At the start, the global execution context would be the first on the stack
- Anytime a function is invoked it is added onto the stack
- When a function has finish running through the creation and execution phase, it gets popped off the stack
- Javscript is single threaded and only 1 task in the stack can be executed
- If a function is not terminated properly and doesn't get popped off the stack, an error will occur which is stack overflow
Variable Environment
- Each execution context has their own variable environment
- Stores all variables and function declarations within the current execution context
- You can also keep the variable environment in memory, which is a closure
- But what happens if the Javascript engine cant find a local variable in the local execution context? It will look to its parent. This is what the scope chain is.
Scope Chain
- Scope: refers to the visibility and accessibility of variables and function
- first the javascript engine will check the local execution context for a variable, and if it can't find it, it will look to the parent or outer context, and goes up the chain until it reaches the global scope
- Child execution context can reference any variables in its parent execution context but a parent can't view a childs execution context
- If the variable could not be found anywhere, then it throws referenceError
Closure
- When you have an inner function declared inside of an outer function
- The inner function creates a closure to the outer variable environment. So after the outer function finishes and gets popped off the stack, there is still a reference to the context of the outer function
- As discussed from the scope chain, the engine will look in the current context of the inner function and if it can't find a variable it will look to the outer scope. In this case it will look at the closure
- This closure will continue to stay in memory, until nothing else is referencing it, or the javascript file finishes executing
function outer() {
var outerScopeVar = "variable from outer"
function inner() {
console.log(outerScopeVar)
}
const num = Math.random()
return num > 0.5 ? inner : (v) => v
}
var closure1 = outer()
closure1()
var closure2 = outer()
closure2() // Creates own seperate closure from closure1