Skip to content
Logo matthiasboehm.com

Matthias Böhm

Understanding JavaScript Execution - JS Fundamentals
  • JavaScript
  • Fundamentals

Understanding JavaScript Execution

Understanding JavaScript Execution - JS Core Fundamentals


JavaScript is the language of the Internet and being fluent in writing JavaScript is essential for almost any software development project regarding the world wide web. While many developers are proficient in writing JavaScript code, most don't know about the Core Fundamentals of JavaScript.

In this multi-part series we will take a peek behind the curtain and learn how JavaScript works. We will dive deep into the core fundamentals of JavaScript, going way beyond basic syntax and uncover the secrets that power your code.

This is stuff I wish I knew when I first started learning and working with JavaScript. This I why I created this serious to give you all the information to really understand JavaScript and its magic behind the scenes.

Overview of Topics

In this first part of the series we will lay the groundwork by exploring the JavaScript engine, which is at the heart of JavaScript execution. We will talk about its components, popular JavaScript engines, and how they interpret and execute JavaScript code.

JavaScript Engine

At the core of JavaScript execution lies the JavaScript engine, the fundamental component that processes and executes JavaScript code within web browsers or other environments. It operates by interpreting the JavaScript source code, parsing it into a structured format, and then translating it into executable instructions.

The JavaScript Engine has an execution environment which manages various tasks such as memory allocation, data type handling, and execution of functions and statements according to the specifications of the JavaScript language (the ECMAScript standard). It integrates closely with the browser's rendering engine, allowing it to interact with the Document Object Model (DOM) and add dynamic behavior to web pages.

Popular JavaScript Engines

There are several JavaScript engines available in modern web browsers and on the server side. The most two popular examples are:

  1. V8 Engine: Developed by Google, V8 is the JavaScript engine used in Google Chrome and several other Chromium-based browsers as well as in Node.js. Known for its speed and efficiency, V8 compiles JavaScript code into machine code for faster execution.

  2. SpiderMonkey: Developed by Mozilla, SpiderMonkey is the JavaScript engine used in Mozilla Firefox. It was one of the first JavaScript engines remains one of the most prominent examples of JavaScript engines to date,

Other notable JavaScript engines are JavaScriptCore (Apple, Safari), Chakra (Microsoft, Internet Explorer), Rhino (Mozilla, for Java applications) and JerryScript (leightweight JS engine for microcontrollers).

How does the JavaScript engine work?

Let's break down how the JavaScript engine works to better understand it:

  1. Parsing: The engine starts by parsing (converting) the JavaScript source code, breaking it down into individual tokens and building a syntax tree from it (called Abstract Syntax Tree) to represent the structure of the code.

  2. Compilation: Next the engine compiles the code into bytecode or machinecode, so it can be more efficiently executed by the engine.

  3. Optimization: Most JavaScript engines use optimization techniques such as just-in-time (JIT) compilation for better performance. This could mean identifying and optimizing frequently executed code paths and other performance optimizations.performance enhancements.

  4. Execution: When the code is compiled an optimized it is executed by the JavaScript engine within its runtime environment. This means the engine will manage memore, handle different data types and execute JavaScript statements and functions according to the JavaScript (ECMAScript) language specifications.

  5. Integration: When the JavaScript engine runs inside the web browser (as opposed to on the server side like Node.js), it integrates closely with the browser's rendering engine. This means it has access to the Document Object Model (DOM) and the Web APIs to dynamically change websites at runtime.

  6. Feedback-driven Optimization: Lastly, some JavaScript engines use so called feedback-driven optimization techniques. This means that runtime information about code execution is used to further optimize the code execution for future usage. This can even include dynamically recompiling code and other runtime optimizations.

Lexical Structure and Parsers

Every programming languages has a certain set of rules that define how exactly you can write code in it. This set of rules is what we refer to as the "lexical structure" of the language.

What is Lexical Structure?

Imagine you're learning a new language. There are certain rules you need to follow, right? For example in English, sentences typically follow a certain structure which is called "subject-verb-object". You wouldn't say "Cherry the red is", you would say "The cherry is red". Similarly, programming languages have their own rules for how code should be written. This is called the lexical structure.

In JavaScript, the lexical structure includes rules for things like:

  • Comments: Comments can be single-line (using //) or multi-line (using /* */). They are ignored by the JavaScript engine and are used to add notes or descriptions in the code.
  • Identifiers: Identifiers are names. In JavaScript, you can use them to name variables, functions, labels, and so on. There are rules for what characters can be used in identifiers.
  • Keywords: These are special words reserved by the language itself. Words like varfunctionifelsefor, etc., have special meanings and can't be used in other ways.
  • Literals: Literals represent values in JavaScript. For example, 123 is a so called numeric literal, "hello" is a string literal, and true is a boolean literal.
  • Operators: Operators are used to perform operations on values and variables. For example + is an addition operator, - is a subtraction operator, and == is an equality operator.
  • Whitespace and line breaks: In JavaScript, spaces, tabs, and newlines are generally ignored, but they can be used to make the code easier to read.

What is a Parser?

Now that we've written our JavaScript code following the lexical structure, we need to turn this code into something that the computer can understand and execute. This is what the "parser" is good for.

A parser is a program that reads our JavaScript code and converts it into a format that the computer can understand. You can compare it to a translator: Up until know our code is just text that the computer doesn't understand. The parser turns the code into a series of instructions that the computer can follow and execute.

Here's how the Parser works:

  1. Tokenizing: The parser starts by breaking up the code into small pieces, called "tokens". A token is a meaningful unit of code, like a keyword, an identifier, a literal, and so on. This process is also known as "lexical analysis".
  2. Syntax analysis: Next, the parser takes these tokens and arranges them in a way that represents the structure of the code. The parser creates a structure called "Abstract Syntax Tree" (AST). Each node in the AST represents a unit of code. This step is also know as "parsing".
  3. Error handling: During this process, the parser also checks for errors. If it encounters something that does not follow the rules (the lexical structure), it will stop and throw an errror.

So to summarize, the parser takes our JavaScript code, breaks it down into tokens, arranges a structure that represents the code and is know as "Abstract Syntax Tree" (AST) and also checks for errors. This is a highly important step in the JavaScript execution process, because this is how our code gets turned from text into something the computer can understand and execute.

Understanding the Abstract Syntax Tree (AST)?

Let's take a deep dive into the Abstract Syntax Tree (AST) and explore how exactly it works and looks like. The Abstract Syntax Tree (AST) is a simplified version of the code structure. It removes less important details to highlight the main parts of the code, this is why it is called "abstract".

To use an analogy, the AST is like an instruction manual for a set of LEGO pieces (blocks of different sizes, colors and shapes). The AST tells us how these pieces fit together and form the whole program - or a specific LEGO model to stay in this analogy.

Let's look at an example. Consider the following JavaScript code:

let sum = 4 + 2;

How does the Abstract Syntax tree look for this code? Let's see:

VariableDeclaration
|
|-- Identifier (sum)
|
|-- BinaryExpression (+)
    |
	|-- Literal (4)     
	|     
	|-- Literal (2)

As you can see in the AST, this would be represented as a tree with three branches:

  1. A branch for the let keyword, which tells us that we're declaring a variable.

  2. A branch for the variable name sum.

  3. A branch for the operation 4 + 2. This branch would have its own two sub-branches: one for the number 4 and one for the number 2.

So, the AST represents the structure of your code in a way that is easy for the computer to understand and execute. It's used by the JavaScript engine to run your code, and by other tools to analyze or transform your code.

Understanding the concept of an AST is important for understanding how JavaScript is parsed and executed. It's also useful for understanding how many code analysis and transformation tools work, because this is a commonly used pattern.

Conclusion

In this article, we have taken a deep dive into the core fundamentals of JavaScript explored some of the behind-the-scenes magic that makes JavaScript work.

We've explored the JavaScript engine, its components, and how it interprets and executes JavaScript code. We have looked at popular JavaScript engines like V8 and SpiderMonkey and discussed how these engines parse, compile, optimize, and execute JavaScript code.

Next, we have covered how JavaScript code is structured. Just like how the English language has rules for sentences, JavaScript has rules for how code should be written. This is called the "lexical structure". It covers everything from how to write comments to how to name variables and use operators.

Then, we have talked about the parser. The parser is like a translator. It takes your JavaScript code and breaks it down into small, understandable pieces called "tokens". It checks for errors and creates something called an "Abstract Syntax Tree" (AST).

Lastly, we have learned about the AST itself, which is a tree-like representation of your code that the computer can easily understand and work with. It shows how all the pieces of your code relate to each other and in essence represents your whole program.

Understanding these core fundamentals of JavaScript personally helped me so much with writing better code and develop a kind of intuition for the JavaScript programming language.

Thank you for reading and look out for the next parts of this series, where we will dive even deeper into further JavaScript core fundamentals.

📢 Never miss an article

  • ✔️ Receive in-depth insights for web developers and software engineers
  • ✔️ Learn JavaScript and web development the proper way
  • ✔️ No spam. Unsubscribe at any time

Join the newsletter and power up your web dev game ☝️


Profile picture Matthias Böhm round
·4 min read