7. Objects and prototypes: the prototype chain, classes as sugar
Every JS object has an internal link to another object — its prototype —
forming a chain that property lookups walk up until found or the chain ends
at null.
const animal = { eats: true };
const rabbit = Object.create(animal); // rabbit's prototype is `animal`
rabbit.hops = true;
rabbit.eats; // true — not own property, found via the prototype chain
rabbit.hops; // true — own property
Object.getPrototypeOf(rabbit) === animal; // true
class is syntax sugar over exactly this mechanism — no new object
model, just a cleaner syntax for prototype-based inheritance plus real
private fields:
class Animal {
#internalId; // truly private — inaccessible outside the class
constructor(name) { this.name = name; this.#internalId = crypto.randomUUID(); }
speak() { return `${this.name} makes a sound.`; }
}
class Dog extends Animal {
speak() { return `${super.speak()} Specifically, a bark.`; }
}
new Dog("Rex").speak();
// "Rex makes a sound. Specifically, a bark."
// Under the hood this is equivalent to:
// Dog.prototype = Object.create(Animal.prototype);
// Dog.prototype.speak calls Animal.prototype.speak via `super`