I've been coding in JavaScript for some time now, but when I just started coding I was not sure or did not even care much as to how the engine was handling code and executing it behind the scenes.
I found some of the factors surprising because what it is actually doing in the back is different that what we would assume by its behaviours.
I think it's important for all developers to know at least the basics of it, so I will briefly discuss the fundamentals.
(Some of my understandings could be wrong.. Feel free to correct me in the comments if so!)
JavaScript is single-thread
JavaScript is a synchronous and single threaded language, meaning only one task can be handled at a time.
This probably would surprise a lot of developers as we use methods like setTimeout
, fetch
that run asynchronously, which is why I used to think JavaScript was not a single-threaded language.
Execution Context
The first thing JavaScript engine does when executing is to create something called global execution context
, and it consists of two phases:
Creation phase:
It creates a global object. This global object is different for browser and Node.js environment. For browsers, this would be the window object containing document objects, etc which do not exist in global object for Node.js.
The engine also looks at each variable and function definition and store them in memory as undefined.
Execution phase:
During this phase, the variables are assigned actual values.
As for functions, the engine skips the lines where functions are defines, and where a function is invoked, the engine creates a new execution context called function execution context
which follows the same phases as the global execution context for its scope.
It repeats the same step for other functions.
Hoisting
When a variable is defined using var
keyword, the variable is created in global scope of memory as undefined
, meaning if the variable were to be used before it is defined, it has a value and it is undefined
.
This behaviour is called hoisting
.
As for functions, they are stored during the creation phase and it will go through its creation and execution phases when they are invoked, which means they are also hoisted and accessible even if they are physically defined after the lines in which they are invoked.
let
and const
were introduced in ES6 whereby variables are stored in block scope of memory, which make their values of undefined
inaccessible during the execution phase unless they are defined before they are accessed.
I have somewhat known about this concept, but it was only recently that the variables and functions defined with let
or const
are also hoisted.
I used to think that they were not even hoisted.. The truth is
they ARE hoisted but they are just not in an accessible scope in memory.
Asynchronous tasks
As briefly mentioned in the beginning, I used to think that JavaScript was multi-threaded because of its "asynchronous features".
The truth, however, is that JavaScript was just using APIs to implement those tasks on the side.
For browsers, they are called Web APIs which include methods like fetch
and setTimeOut
. They are NOT part of JavaScript spec itself.
Task queue & Event loop
Callback functions passed in an asynchronous method get put into what is called task queue
.
Task queue is FIFO (First In First Out) meaning the first task put into the queue is the first task to get removed and put onto the execution stack, and this is done by the help of event loop
which continuously check and see if execution stack is clear and push a task onto it if so.
Wrap-up
I explained just the basics and I honestly have not dived too deep into details myself on this topic, but I thought this would be enough content for beginners - intermediate developers and nice knowledge to have.
Top comments (0)