← the guideThe Web Opens

§ 02 — Eras · 1995

JavaScript

written in ten days; runs the world’s screens

Left: era context, features, and the 101 hello. Right: 3 core concepts, 3 deeper 201 lessons, the factorial specimen, and where JavaScript lives today — each column scrolls on its own.

creators
Brendan Eich, Netscape, 1995
status
alive (ubiquitous) · every browser, plus servers via Node
lineage
← Scheme→ TypeScript

The problem it solves

The browser needed scripting, immediately. Eich shipped Scheme dynamics in C’s clothing — in ten days.

The problem it carries

Designed in ten days: coercion surprises, this-binding puzzles — and permanent: the language the web can never remove.

Key features

first-class functions
Functions are values: passed, returned, stored in objects and arrays.
closures
A function remembers where it was born — the module pattern and half of JS idiom follow.
prototypes
Objects delegate to a shared prototype: inheritance without classes.
the event loop
One thread and a queue; promises schedule continuations on top of it.

101 — hello, world

Session one is the smallest program that still counts as speaking JavaScript: what every tutorial prints first, in the dialect that mattered when the language arrived (1995).

the first program1995
console.log("Hello, world");

101First contact — hello world and 3 ideas that define how JavaScript reads. 201 — 3 lessons on mechanisms you meet after the factorial specimen: the sharp edges practitioners actually use.

101 — core concepts

3 fragments, each naming a habit of mind in JavaScript. Read the note, then the code — together they are the 101 in one sitting.

01 — closures

Functions remember where they were born — the module pattern and half of JS patterns follow.

function counter() {
  let n = 0;
  return () => ++n;
}
const tick = counter();   // tick(); tick(); → 1, 2

02 — arrays & methods

Scheme’s functions over C’s syntax — map/filter/reduce are the daily bread.

const ports = ["osaka", "genoa"];
ports
  .filter(p => p.length > 4)
  .map(p => p.toUpperCase());

03 — async/await

Asynchronous, single-threaded, but written like sync — promises under the hood.

async function crew() {
  const r = await fetch("/api/crew");
  return r.json();
}

201 — going deeper

The 201 assumes you have read the 101 and the specimen. Each lesson is one mechanism — what it is for, how it looks in code, and the trap or payoff that makes JavaScript distinctive at scale.

  1. the event loop and microtasks
  2. scope, closures and this
  3. modules and the toolchain

the event loop and microtasks

Timers, promises and microtasks run in a precise order: the call stack empties, microtasks flush, then the next macrotask begins. Most “async bugs” live here.

console.log('a');
setTimeout(() => console.log('b'));
Promise.resolve().then(() => console.log('c'));
console.log('d');
// a, d, c, b

scope, closures and this

var is function-scoped and let/const are block-scoped; arrow functions capture this lexically, which fixes most classic callbacks.

const crew = [{ name: 'perch', port: 'osaka' }];
crew.forEach(function (s) {
  setTimeout(() => console.log(this, s.name)); // `this` wrong
});
crew.forEach((s) => setTimeout(() => console.log(s.name)));

modules and the toolchain

ES modules are static, tree-shakeable and hoisted; the bundler only rewrites URLs. That is the whole modern JS delivery story.

// crew.js
export const crew = [{ name: "perch" }];
// main.js
import { crew } from "./crew.js";

The specimen — factorial

The closure: functions that remember where they were born — Scheme semantics in C’s clothing, shipped in ten days, now running nearly every screen on Earth.

the closure1995
function counter() {
  let n = 0;
  return () => ++n;
}
counter()();  // 1

Run it today

installbrew install node

runnode fact.js

Where it is now

Every web page you have ever opened; Node runs a large share of server-side code, and this very page is JavaScript.