Object-oriented JavaScript, from the beginning.
Fifteen lessons that take you from “what is an object” to designing your own classes. Every example runs on the page, so you never have to take a claim about the language on trust.
- 15 lessons
- 3h 10m of reading
- No install, works offline
Where this is going
You are not expected to understand the code below yet. Run it anyway. By lesson 15 every line will be something you could have written, and you can come back here to check.
// A class describes how to build something.
class Bus {
#seatsLeft; // private: nothing outside can touch it
static built = 0; // belongs to the class, not to one object
constructor(plate, seatsLeft) {
this.plate = plate; // public data, on this instance
this.#seatsLeft = seatsLeft;
Bus.built++;
}
get seatsLeft() { return this.#seatsLeft; } // readable, not writable
book(n) { // behaviour, shared by every bus
if (n > this.#seatsLeft) throw new RangeError(`${this.plate}: only ${this.#seatsLeft} left`);
this.#seatsLeft -= n;
return this; // returning this lets calls chain
}
describe() { return `${this.plate} has ${this.#seatsLeft} seats left`; }
}
// Inheritance: a more specific description, built on the general one.
class LuxuryBus extends Bus {
constructor(plate, seatsLeft, extra) {
super(plate, seatsLeft); // build the Bus part first
this.extra = extra;
}
describe() { // same name, different answer: polymorphism
return super.describe() + `, with ${this.extra}`;
}
}
const fleet = [
new Bus('ABJ-772-KM', 6),
new LuxuryBus('LAG-441-XA', 9, 'air conditioning'),
];
// One loop, two types, each answering in its own way.
for (const member of fleet) console.log(member.describe());
console.log('built so far:', Bus.built);
console.log('a LuxuryBus is also a Bus:', fleet[1] instanceof Bus);
fleet[1].book(3);
console.log(fleet[1].describe());
try { fleet[0].book(99); } catch (err) { console.log('refused:', err.message); }
Output
Part one — Objects
What an object is, what it can do, and the one keyword everything turns on.
- 01 What an Object Actually Is Make an object by hand and read values back out of it. 9 min
- 02 Properties and Methods Give an object behaviour, not just data. 11 min
-
03
The Word
thisPredict whatthisis in any call, and fix it when it is wrong. 15 min - 04 Factory Functions Build many similar objects from one function. 10 min
-
05
Constructors and
newExplain exactly whatnewdoes, step by step. 13 min
Part two — The machinery
Prototypes, class syntax, and where to keep state so it stays yours.
- 06 Prototypes and the Chain Above Trace a property lookup all the way up the chain. 16 min
-
07
class: the Same Thing, Less Typing Write a class with a constructor, fields and methods. 12 min - 08 Encapsulation Hide internal state behind a deliberate public surface. 13 min
- 09 Getters and Setters Expose computed values and validate assignment. 11 min
- 10 Static Members Put counters, factories and constants where they belong. 10 min
Part three — Design
Reuse, substitution, and knowing which of these tools not to reach for.
-
11
Inheritance:
extendsandsuperExtend a class correctly, including its constructor. 15 min - 12 Polymorphism Write code that handles many types through one interface. 12 min
- 13 Abstraction Design an interface that hides the machinery behind it. 11 min
- 14 Composition Over Inheritance Choose between "is a" and "has a", and refactor from one to the other. 14 min
- 15 SOLID and Four Real Patterns Name the smell, then name the fix. 18 min
Nothing marked done yet. Lesson 01 is a good place to start.
What object-oriented actually means
Four ideas carry the whole subject. JavaScript's answers to them are unusual enough that learning OOP from a Java or Python tutorial will actively mislead you.
Encapsulation
Keep data and the operations allowed on it together, and let the outside world touch only what you deliberately expose. A balance that can only change through deposit and withdraw cannot silently go negative.
Lessons 02, 04, 08, 09
Abstraction
Decide what the person using your object never needs to know. They ask for the total; they do not think about how it is stored.
Lessons 13, 14
Inheritance
Build a specific thing on top of a general one so shared behaviour is written once. The most powerful of the four and by a wide margin the most misused, which is why two lessons are spent on when to refuse it.
Lessons 06, 11, 14
Polymorphism
Many different objects answering the same request, each in its own way, so the calling code stops caring which one it has.
Lessons 12, 15
How to work through it
The order matters more here than in most courses, because lessons 04 to 07 are one continuous argument: factories, then constructors, then prototypes, then class. Read them in sequence and class arrives as an obvious shortcut. Skip to class first and it stays magic, which is where most working JavaScript developers are stuck.
- Read with this page in one window and your editor in the other.
- Run every example. When the output surprises you, change a line and run it again. That is the whole study method.
- Do the task at the foot of each lesson before moving on. It is short on purpose.
- After lesson 07 and again after 15, work through the drills, then build the project.
Everything else
A blank editor with the runner attached, plus six starters that each isolate one idea.
Drills29 graded exercises with starter code and a worked solution you can reveal when stuck.
Quiz30 questions with an explanation on every answer, right or wrong. Scored, not graded.
ProjectBuild a small booking system in eight runnable steps, using every idea in the course.
CheatsheetEvery syntax form in the course on one printable page, with the gotcha next to each.
Glossary42 terms in plain language, each with the short version and the fuller version.
What this is, honestly
A course written to be read offline. It has no account, no backend, no analytics and no network calls of any kind; the fonts are inlined into the stylesheet and the syntax highlighter is a few hundred lines in assets/js/highlight.js. Your progress and anything you type into an editable panel are kept in this browser's localStorage and nowhere else, so clearing site data clears them.
Code you type into a panel runs in your own browser, in a function scope with a shadowed console, always with "use strict" applied. That is what makes the examples honest. It also means an editable panel will run whatever you paste into it, so treat it the way you would treat your own devtools console.