Mehdi Tmimi JavaScript

JavaScript Chapter 01 · Under the hood

How does JavaScript run?

Your JavaScript runs in Chrome, in Node.js, on your phone. Who actually runs it, and what changes from one place to another?

The engine runs your code. The environment around it adds the rest: the page in a browser, files in Node.js.

The short answerAn engine runs it: an interpreter starts your code at once, and the parts that run often are compiled to machine code. Each browser ships an engine (Chrome and Edge share V8); Node.js is built on V8 too. The language stays the same; only the environment around it changes.

JavaScript in brief

JavaScript follows a standard named ECMAScript. A committee, TC39, adds a new edition every year: that is what “ES6” or “ES2022” means in a tutorial or a config file.

Three traits to know:

  • Dynamically typed.

    A variable has no type; its value does. People often say “untyped”.

    the language · same in every engine
    let score = 10;    // a number
    score = 'ten';     // now a string: allowed
  • Object-oriented, through prototypes.

    An object can inherit straight from another object. The class keyword is built on this.

    const animal = { breathes: true };
    const cat = Object.create(animal);
    cat.breathes;      // true, found on animal
  • Functions are values.

    Store a function in a variable, pass it, return it.

    const greet = (name) => 'Hi ' + name;
    // greet is passed to map like any value
    ['Sara', 'Ali'].map(greet); // ['Hi Sara', 'Hi Ali']

Why an engine?

Your processor runs only machine code; your file is text. The engine bridges the two.

  1. Read: parse the whole file and check the syntax (one syntax error, and no line runs), then turn it into bytecode: short, simple instructions.
  2. Interpret: the interpreter runs them at once; your program starts fast.
  3. Count the calls: a function that runs often becomes “hot”.
  4. Compile what is hot: the optimising compiler turns that function into machine code. JavaScript declares no types, so it bets on what it saw: “this function always gets numbers”.
  5. Undo if the bet fails: a string arrives? Drop that machine code, back to the interpreter (deoptimisation). The engine changes the speed, never what your code computes.

Interpreted or compiled? Both, while the program runs: that is just-in-time (JIT) compilation.

Engines and their environments

Each browser ships an engine: V8 in Chrome and Edge, SpiderMonkey in Firefox, JavaScriptCore in Safari. Edge used Microsoft’s own engine, Chakra, until 2020.

An engine never works alone: a program carries it and gives it an environment, the extra things your code can use beyond the language, such as the page or the files. Outside the browser:

  • Node.js is a runtime environment built on V8, with its own tools, such as fs and process.
  • React Native apps (phone apps written in JavaScript) run on Hermes, an engine Meta built for phones. Hermes turns your JavaScript into bytecode ahead of time, when the app is built for release, so the app starts faster.
  • VS Code is built with Electron, which packs a browser and Node.js into one app: your editor itself runs on V8.

The core does not change

The language is the same everywhere: variables, arrow functions, promises and objects behave alike in every recent browser and Node.js, because every engine implements ECMAScript.

What changes is what the environment adds:

  • a browser adds the page: document, window, clicks;
  • Node.js adds the machine: fs for files, process for the running program.

Code works here and breaks there? Ask first: the language, or the environment?

Try it

The rule of this course

An assistant will type most of your code. Predict it, write it once yourself, test it. If you cannot explain a line, it is not yours.

Same line, two places

snippet
console.log('Hello');

The Node.js Playground: desktop Chrome or Edge.

  1. Web Playground: press Run. Hello appears in the Console panel.
  2. Node.js Playground: press Run. Hello appears in the Console tab (the first Run takes a few seconds).
  3. Write it once yourself: replace Hello with your name, run again.

You should see

Web Playground · Console panelHello
Node.js Playground · Console tabStarting Node.js… (the first run takes a few seconds)
▶ node index.js
Hello
✓ Finished (code 0)

One difference

snippet
console.log(document);
Predict first

What happens in each playground?

Check after you predict
Web Playground · Console panel#document
Node.js Playground · Console tabReferenceError: document is not defined
✗ Crashed (code 1) — the error is above

The Web Playground prints #document: the page itself. The browser adds document; Node.js does not, so it stops: document is not defined. Read the line that names the error. The Node.js Playground runs Node.js inside your tab, but your code gets Node’s environment, not the page’s: same language, different environment.

Interview corner

Answer it like an engineer

Answer each one out loud, in three parts, then compare with the model.

  1. Claim
  2. Mechanism
  3. Consequence
  1. “Is JavaScript compiled or interpreted?”

    Compare with the model
    Claim
    Both: interpreted first, compiled where it pays off.
    Mechanism
    The engine parses the code and turns it into bytecode; an interpreter runs it at once; the functions that run often are compiled to machine code by an optimising compiler, which bets on the types it has seen; if a bet fails, the engine deoptimises and goes back to the interpreter.
    Consequence
    Fast start and fast hot code; code that keeps its types stable stays fast.
  2. “What is the difference between JavaScript, V8 and Node.js?”

    Compare with the model
    Claim
    A language, an engine, a runtime environment.
    Mechanism
    ECMAScript defines the language; V8 is an engine that runs it; Node.js embeds V8 and adds its own tools, such as fs and process.
    Consequence
    The language travels with you; each environment’s tools stay where they are.
  3. “Why does document work in Chrome but not in Node.js?”

    Compare with the model
    Claim
    document is not part of the language; the browser adds it.
    Mechanism
    Every engine runs the same ECMAScript; each environment adds its own objects around it: the page (document, window) in a browser, the machine (fs, process) in Node.js.
    Consequence
    When code breaks in one place only, check whether it uses the language or the environment; browser code run on a server stops with document is not defined.

Quick check · 5 questions

Who maintains the ECMAScript standard?

See the answer

TC39, a committee of Ecma International, maintains ECMAScript, and Ecma publishes one edition a year. Engine makers take part, but no single one owns the language.

In V8, what runs your code first?

See the answer

The interpreter starts at once; only the parts that run often are compiled to machine code later.

A function always received numbers, and V8 compiled it to machine code. Now it receives a string. What happens?

See the answer

The compiler’s bet failed, so the engine deoptimises. It changes the speed, never what your code computes.

Which engine does Node.js run on?

See the answer

Node.js is a runtime environment built on V8, the engine of Chrome.

Which one is part of the language, the same in a browser and in Node.js?

See the answer

ECMAScript defines Promise, so every engine has it. A browser adds document; Node.js adds fs and process.

Recap

  1. JavaScript follows ECMAScript, a standard TC39 updates every year.
  2. The processor runs only machine code; an engine runs your JavaScript.
  3. Parse, bytecode, interpret, compile the hot parts; a failed bet returns to the interpreter.
  4. Each browser ships an engine; one engine, V8, runs in Chrome, Edge, Node.js and VS Code.
  5. Same language everywhere; the environment adds the rest, such as document or fs.

Sources

← All chapters