How does JavaScript work?

Let's learn about web APIs, even loop, call stack and many more

How does JavaScript work?

Now let's go from the definition of javascript all the way up to understanding how it really works. May be you already know these few things at top, but let's just start from the ground level.

So, What is javascript?

JavaScript is a dynamically typed, single-threaded, high-level, interpreted programming language commonly used to create a functional website. I know it wasn't an awesome definition to digest, so let's break it down:

⚒Dynamically typed:

Dynamically typed means you need not to strictly define the type of a variable or return type of function. Let's do a quick comparison between C++ and JavaScript code.

Note C++ is statically typed whereas JavaScript is dynamically typed.

C++ style:

double PI = 3.141593;

int area(int length, int breadth){
    return length * breadth;
}

int area_of_rectangle = area(5,4);

JavaScript style:

const PI = 3.141593;

function area(length,breadth){
    return length * breadth;
}

var area_of_rectangle = area(5,4);

In short, you need to know what type of value you are storing in the case of C++ but that's not the case with JavaScript. I really hope it is now crystal clear to you.

🏦High level programming language

In a simple definition, high level programming language (in short HLL) means a computer language that is more readable by human beings but it requires to get converted into machine code cause we all know computers only understand 0's and 1's at the end of the day.

👩‍💻Interpreted programming language

Of course, to convert HLL into Machine Level language, we need some converters. And there are two of them, one is compiler and another is interpreter. JavaScript is get interpreted(fancy word to say converted) by the interpreter, so it is called interpreted programming language.

⚙Single-Threaded

Single-Threaded means that JavaScript can only run one instruction at a time, even if your CPU has multiple cores and available threads.

Where JavaScript is used?

Well, there is a long list when it comes to the real application of javascript. JavaScript is used in full-stack (both client-side and server-side) web development, mobile application development, machine learning, Game development (there are lots of areas, maybe one more field gets added while I finish writing its uses).

Short history of JavaScript:

Brendan Eich created JavaScript in 1995 while he was at Netscape Communications Corporation. It was originally developed by Netscape as a means to add dynamic and interactive elements to websites. Initially, it was only used on the client-side, now it has a diverse field, thanks to the introduction of nodejs.

Javascript engines

There is something called javascript engine which executes JavaScript code inside of browsers. And different major browsers out there have their own JavaScript engines. Let's look at some of them:

  • Chrome has v8.
  • Mozilla Firefox has SpiderMonkey,
  • Microsoft Edge has Chakra,
  • Safari has JavaScriptCore

Maybe you are thinking that we can run JavaScript outside of the browser. Then you are absolutely right. We can do that with the help of Nodejs. And Nodejs is based on Chrome's v8 engine that means we are using the same engine inside and outside of a browser. When I'll be talking about JS engine, it's v8 engine for the rest of the article.

How does javascript code run?

When the JavaScript file is loaded in the browser, the JavaScript engine will execute each line of the file from top to bottom (to simplify the explanation we are avoiding hoisting in JS). ECMAScript Standards is being followed by the JavaScript engines. JavaScript engine will parse the code line by line, convert it into machine code and then execute it.

JavaScript is a single-threaded language at runtime. This means that the execution of the code is done but only one piece at a time. As the code is being executed sequentially, so any code that is taking a longer time, as usual, will block the path of other code that is required to be executed after that.

Execution context

Everything in JavaScript happens inside an Execution Context. And it has two components inside it:

  1. Memory Heap
  2. Call stack

Memory heap and call stack in JavaScript

The Javascript Engine does a lot of work for us. But the biggest thing is reading our code and executing it. Memory heap stores and writes information — data for our app(variables, objects, etc..). And call stack keeps track of what's happening to our code line by line. well let's dive deeper:

We will be referencing to the code snippet below, while discussing about memory heap and call stack.

    const name = "Aashish";
    function last(){
        console.log("I'm last");
    }

    function first(){
        console.log("I'm first");
    }

    first();
    last();

Memory Heap

Heap is a large unstructured data structure that stores all the dynamic data like function definitions, objects, arrays, etc. In the above code example, the name is being stored somewhere. Actually, the value Aashish is stored somewhere in memory and name is pointing to it. Then the whole code inside of last(){} is stored in a memory and after first(){} is also being stored. The memory occupied in the heap continues to exist even after the JavaScript code execution has been completed. They are removed by the JavaScript Garbage Collector.(Uff, that was epic)

Call stack

Call stack follows the Last In First Out (LIFO) principle (the last item to enter the stack will be the first item to be removed from the stack). It is used to keep track of where we are. First, a global execution context is created on the bottom of the call stack. Each function has its own execution context called functional execution context which gets inserted on the top of the global execution context when the function is called in the code. In this particular case, first() is stacked on top when it is called, after it gets executed, first() pops out of stack and last() is stacked, again last() gets executed and the call stack gets empty. (Just look at the visual below)

Functions call on call stack

This much is sufficient to know for now but there is more (it will get so long).

JavaScript Runtime Environment (JRE):

So far we have discussed the JavaScript engine, but the JavaScript engine doesn’t run in isolation. It runs inside an environment called JavaScript Runtime Environment along with many other components. JRE is responsible for making JavaScript asynchronous. It is the reason JavaScript is able to add event listeners and make HTTP requests asynchronously.

JRE is just like a container which consists of the following components:

  • Web API
  • JS Engine
  • Callback Queue or message queue
  • Event Table
  • Event loop

Web APIs

A browser can perform many tasks like getting the user's location, turning on/off bluetooth, storage tasks, timer-related tasks, and many more. And we as developers need these things. So, all these things can be accessed by JavaScript via Web APIs. That's it, now we have all these things inside one place and that place is a window object.

Some web APIs:

  • localStorage
  • setTimeout()
  • console
  • DOM APIs
  • fetch()
  • location
  • alert()
  • and others

Maybe you didn't know setTimeout is not a part of JavaScipt

Callback Queue or message queue

A callback Queue is also called an event queue. An event queue holds all the events that need to be executed in a certain order. The thread then goes through this queue and executes them until the queue is empty. The callback queue follows First In First Out approach.

Event queue in javascript

Event Loop

Methods are executed by the JavaScript engine, only if it is present in the execution context stack. So, for the execution of any method, we need to move that method from the callback queue to the execution context stack. This is what the event loop does! The event loop continuously checks if the execution context stack is empty and if there are any messages in the event queue. It will move the method from the callback queue to the execution context stack only when the execution context stack is empty.

And with all of these components, javascript code is executed in front of our eyes but behind the schene(I know this was a terrible joke😅). But hey that's all javascript code needs to travel through before getting executed by their respective javascript engines, some operations may differ according to the browser you use due to javascript engines but most of these engines are non-distinguishable. And that's all for today. Hope you will have a great day ahead.