How does JavaScript work?

Akash Singh
5 min readApr 22, 2020

“JavaScript and Java are completely different languages, both in concept and design.”

JavaScript is a high-level, often just-in-time compiled and multi-paradigm programming language.

just-in-time — code gets compiled when it is needed, not before runtime.

multi-paradigm — javaScript supports both object-oriented programming with prototypal inheritance as well as functional programming.

JavaScript was created by Netscape’s Brendan Eich in 1995. It was originally intended as a simpler scripting language for websites, complementing the use of Java for more complex web applications, but its tight integration with Web pages and built-in support in browsers has caused it to become far more common than Java in the web development.

But unlike other programming languages, javascript is single-threaded. This means that code execution in js is done sequentially which means that we can experience one piece of code blocking another piece of code.

When you visit a site in your browser a single javascript execution thread starts working. This thread is responsible for handling everything like scrolling, listening to DOM events like mouse clicks, printing the webpage. When this single execution is blocked the web page stops responding.

So how javascript handles it?

when an asynchronous event occurs (like a mouse click, a timer firing, or an XMLHttpRequest c.ompleting) it gets queued up to be executed later…. After the initial block of JavaScript finishes executing the browser immediately asks the question: What is waiting to be executed? The browser then picks one and executes it immediately. The rest will wait until the next possible time, in order to execute.

For understanding, this lets first understand javascript runtime.

Javascript runtime environment

Call Stack — region in memory, which operates in FIFO mode. When a new thread is started by a computer program, a new stack is created. Js engine starts pushing functions to be executed on the call stack starting from the parent function.

When a function returns a value or calls a web API, it is popped off the stack and moves to the next function in the stack. This process of parsing a function and popping it off the stack is what they mean when they say Javascript runs synchronously. It does one thing at a time on a single thread.

For example

function main(){  //3  
average() //2
}
function average(){
add() //1
}
main()

the function executed in manner 1->2->3

Heap -

This is where V8 engine stores objects or dynamic data. This is the biggest block of memory area and this is where Garbage Collection(GC) takes place.

Stacks vs Heap

  • Every function call is added to the stack.
  • All local variables including arguments and the return value are saved within the function frame-block on the Stack.
  • All primitive types like int & string are stored directly on the Stack. This applies to global scope as well and yes String is a primitive type in JavaScript
  • All object types are created on the Heap and are referenced from the Stack using Stack pointers. Functions are just objects in JavaScript. This applies to global scope as well
  • Functions called from the current function is pushed on top of the Stack
  • When a function returns its frame is removed from the Stack
  • Once the main process is complete, the objects on the Heap do not have any more pointers from Stack and becomes orphan
  • Unless you make a copy explicitly, all object references within other objects are done using reference pointers

Since JavaScript is single-threaded, it has only one stack and one heap. Hence, if any other program wants to execute something like an HTTP request, it has to wait until the previous program is completely executed. This is really bad for any programming language . Ooops

This is where event loop and callback queues come into action.

So What actually happens

There are a lot of things that keeps on happening in a browser like HTTP calls, mouse click events, delay of execution using setTimeOut() function and lot of scrolling stuff ..think of these all task being performed by a single thread, won’t it reduce the user experience

So what browser does is that it use low level language like C++ to perform these operations and provide clean asynchronous JavaScript API to work with. These APIs are known as Web APIs.

Let's understand the asynchronous behavior using code.

function main(){  
average()
}
function average(){ //2
add()
}
function add(){ //3
setTimeout(callback,3000) //4
}
main() //1

On call-stack how functions are pushed

1 →2 →3 →4

4 contains web API call so it is handed over to Web API with a callback function and popped from stack .then 3 -> 2-> 1 are executed and popped.

Meanwhile, Web API is doing its job in the background and once the job is done, Web API binds the result of that job to the callback function and publishes a message to callback queue with that callback.

The only job of event loop is to look at callback queue and once there is something pending in callback queue, push that callback to the stack.

Event loop pushes one callback function at a time, to the stack, once the stack is empty. Later, stack will execute callback function.

Conclusion

This is how javascript handles the execution of the task in the browser. Node js is a javascript runtime that uses Google’s V8 engine. But Nodejs does not rely only on its event loop. It uses libuv library written in c language to work alongside V8 event loop to extend what can be done in the background.

Nodejs Architecture

NodeJS has an event-loop and can offload tasks to its internal thread pool or the Kernel so that it can execute code while it waits for IO — which allows NodeJS to handle many requests simultaneously, even though it is single-threaded.

--

--