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 — Eras · 1995
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.
The browser needed scripting, immediately. Eich shipped Scheme dynamics in C’s clothing — in ten days.
Designed in ten days: coercion surprises, this-binding puzzles — and permanent: the language the web can never remove.
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).
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.
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, 202 — 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();
}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.
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, bvar 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)));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 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.
function counter() {
let n = 0;
return () => ++n;
}
counter()(); // 1installbrew install node
runnode fact.js
Every web page you have ever opened; Node runs a large share of server-side code, and this very page is JavaScript.