THE UNDERLYING MAGIC BETWEEN YOUR CODE AND THE BROWSER

Kelechi Ogbuka
LearnFactory Nigeria
4 min readMar 4, 2020
image from stock images

As a JavaScript newbie I was told my code is single-threaded and runs one line at the time. Okay, I think I get it. It was a smooth ride until Hoisting, Callbacks and Scoping came along, everything started to go downhill. Why will a console work before it’s function declaration? if declared variables and functions are hoisted first, why do I still see my results in the order which my code appears? How does all this even work?

After some studies, I discovered we have a few guys to thank for this, and they are;

THE EXECUTION CONTEXT :

So basically, this is concerned with how our code gets broken down in chunks within and outside it’s environment or scope before the engine runs them. The execution context starts it’s flow from a global scope (Global Execution Context (GEC)). Once the engine encounters my script, it creates a global object whose job is to store all global functions and variables as properties, proving they can be accessed directly within the environment. Here, hoisting takes place. Declared variables and functions are picked first, then the assigned variables and expressed functions follow suit (This is where hoisting started making sense to me. Since they are picked first, they can be accessed from anywhere in our scope). As execution proceeds, it flows into the functions within the global object. Here, a function context is created for each function(Function Execution Context (FEC)). Note that this happens when the function is called/invoked.

image from level up coding

As seen above, After the execution context is created it’s properties are taken into memory, the global variables above the global functions . At that point before execution, the call stack comes into play.

THE CALL STACK:

The call stack is midpoint between the execution context creation and the final execution of the code. Once the execution context is created, it is pushed to the current stack which in my interpretation is likened to a to-do list where we arrange everything we’re meant to do for the day. Only is this case, the first into the list, leaves last. Here’s an example;

image from snippets of lecture by Phillip Roberts

printSquare() is the parent function and it is stacked below. Above it is a child function square(n) within which resides the return multiply(n,n) which is stacked above it.

image from bit.dev

During execution as seen above, the Second() function leaves the stack first, followed by First() which is the parent to the Second(), then the global execution context(). JavaScript runs line by line in order but not exactly in the order which you wrote it and call stack explains it all. During this process of stacking and executing, what if the engine comes across a function which has been set to run after a certain amount of time? will it wait? Well say hello to the Event Loop.

The Event Loop:

When our execution context encounters a callback, it does not push it to the current call stack. Instead, it is placed in a queue to avoid bumping into a running function. The duty of the event loop is to listen for when the call stack is empty, then check the queue. If the queue is not empty, it pushes the callbacks on the queue one after the other. Unlike the call stack, the first to be queued is the first to leave. Here’s the bigger picture below;

image from Thought and </code>

In the end, our browser does not display our results in the manner which it runs it. Hence, we do not see the hoisting or stacking done behind. So it picks our codes, breaks them down in bits, stacks them, attends to them one by one and appends our result. Yes, magic.

--

--