The Execution Context and The Scope
The Execution Context is a collection of information required to run a function.
It includes variables, functions, and the this
context.
Scope is where the JavaScript engine looks for accessible identifiers (such as variables, functions, and objects) when executing a function. In other words, the scope defines the area where a function can access these identifiers.
When a JavaScript program runs, the engine first creates a global execution context. Each time a function is executed, a new function execution context is created.
The execution context consists of a lexical environment and an outer environment.
The lexical environment contains primitive values and references to objects in the heap, while the outer environment links to the higher-level execution context.
These execution contexts are pushed onto the call stack and are removed when the function completes execution.
The call stack operates just like a stack data structure, where the last execution context pushed is the first to be removed.
The Event loop
The event loop is a JavaScript concurrency model. Concurrency means handling multiple tasks at the same time. However, it does not mean JavaScript runs on multi-threads(although it can offload operations to workers).
JavaScript mostly runs on a single thread, but it gets help from its surrounding environments.
For example, if you want to fetch data from an API server, you use the fetch API, which is a part of the browser’s network stack.
The event loop consists of the message queue, the heap, and the call stack.
I will explain the message queue and heap later in this article.
This YouTube video explains how the event loop works with excellent visualization of the event loop.
The Microtask Queue
The microtask queue holds asynchronous tasks related to promises (like .then()
callbacks) and mutation observers.
Note that the task queue handles network requests, while the Microtask queue handles promises.
As its name suggests, it operates as a queue, meaning tasks are moved to the call stack in a first-in, first-out (FIFO) manner.
The message queue temporarily holds tasks until the call stack is empty and then moves tasks to the call stack.
An important thing to note about the microtask queue is that the event loop executes all tasks in the microtask queue in a single tick. This means that if a microtask calls another microtask, it can lead to an infinite loop.
The Task Queue
The task queue holds asynchronous tasks like network requests, timers and callbacks.
Once all microtasks have been executed, the event loop pulls one task from the task queue and executes it. Unlike the microtask queue, only one task is executed at a time from the task queue.
The Heap
In JavaScript, reference types such as objects, arrays, and functions are stored in the heap.