Introduction to the javascript engine

Mon Sep 09 2024

~ 4 mins

What is it?

When our browsers are generating the content for a page and they come across some javascript code, they don’t actually know how to use the high-level that code we write.

It first needs to be converted into a format the browser and your computer can understand ( machine code ). That’s what the js engine does.

The js engine is just a computer program that’s responsible for reading and executing our js code. The three things that a javascript engine does is:

  1. read code
  2. translate code into machine code
  3. run code

Where is it?

Js engines are one of the core building blocks that make up a javascript-runtime.

Different browsers and different runtime environments come bundled with their version of the javascript engine ( e.g. Chrome uses the V8 engine, Firefox uses SpiderMonkey).

Different js engines handle certain implementation details differently but all of them will be made up of a heap and a call stack.

The heap and the call stack

The heap and call stack are two areas of memory on your computer that store data while the JS engine is running.

  • call stack: used for storing information that has a fixed size e.g. primitive data types
  • heap: used for storing complex objects and data structures.

Unlike the call stack, the javascript engine doesn't allocate a fixed amount of memory for these objects in the heap. Instead, more space is allocated as needed dynamically.

How it works

Whenever a browser is processing an html file and it encounters a <script> tag or an attribute with js code like an onClick ,it sends it to it’s javascript engine.

The engine creates an environment called the execution context to read, translate, and run the code.

The execution context contains the code that is currently running and the objects from memory it needs ( variables etc. )

Execution context

There are two types of execution contexts: global and functional.

global execution context: created when the js engine first starts to run, and it represents the global scope in js.

function execution context: created whenever a function is called and it represents the function’s local scope.

There are two stages in creating an execution context: the creation phase and the execution phase.

Creation phase

During the creation phase of a global execution context, the js engine carries out these tasks:

  • read over the code and stores variables in the global execution context as undefined
  • create a memory heap for storing objects and function references
  • create the global javascript object (e.g. the window object in browsers)
  • create the this object and bind it to the global object.

Execution phase

During the execution phase the engine:

  • reads over the engine reads over the code once more and updates the values values for the variables with their actual values
  • the code is parsed, transpiled into executable byte code and gets executed.

The creation phase of the functional execution context is similar.

Instead of creating the global object, the js engine creates the arguments array, that is a reference to all the parameters of the function.

Call Stack / Execution stack

The execution stack, also known as the call stack, keeps track of all the execution contexts created during a lifecycle of a script.

When a scrips loads in the browser the global execution context is created and placed at the bottom of the execution stack.

The engine then searches for function calls in the code and a new functional execution context is created for that function.

Javascript is a single-threaded which means it can only do one task at a time.

If function A is currently executing, it's execution context will appear in the call stack. If function A calls another function (function B), then function B's execution context is created and placed on top of function A's.

The javascript engine only executes one context at a time, so whichever function has it's execution at the top of the call stack will always be executed first.

As soon as the code within the active execution context is done, the js engine removes it from the top of the stack and moves on to the next below it.