Prototypes and Classes
Sometimes you need many objects that share the same shape. A shop might have hundreds of products. Writing each one by hand would be slow and easy to get wrong. JavaScript gives you two related tools for this: prototypes and classes.
What a Prototype Is
A prototype is an object that other objects can borrow properties from. Every object in JavaScript has a hidden link to a prototype. When you read a property that an object does not have, JavaScript looks at its prototype, then the prototype's prototype, and so on. This chain of lookups is called the prototype chain.
A method is a function stored as a property of an object.
You do not usually write prototype links by hand. Instead, you use a class.
What a Class Is
A class is a blueprint for making objects. It is a cleaner, modern way to set up prototypes. A class lists the methods that every object made from it will share.
class Product {
constructor(name, price) {
this.name = name;
this.price = price;
}
describe() {
return `${this.name} costs $${this.price}`;
}
}
const mug = new Product('Mug', 12);
const pen = new Product('Pen', 3);
console.log(mug.describe()); // Mug costs $12
console.log(pen.describe()); // Pen costs $3New words here:
class Product— starts a blueprint named Product.- constructor — a special method that runs when you create a new object. It sets up the object's own data.
new— creates an object from the class and runs the constructor.this— inside a method, refers to the object the method was called on.mug.describe()runs withthisequal tomug.
mug and pen each have their own name and price, but they share the single describe method through the prototype. That sharing saves memory and keeps behavior consistent.
Inheritance: Extending a Class
A class can extend another class. The new class gets all the parent's methods and can add its own. This is called inheritance.
class Book extends Product {
constructor(name, price, pages) {
super(name, price); // run the parent constructor
this.pages = pages;
}
describe() {
return `${super.describe()} (${this.pages} pages)`;
}
}
const novel = new Book('Exploring JS', 40, 500);
console.log(novel.describe()); // Exploring JS costs $40 (500 pages)extends— makes Book a child of Product.super(...)— calls the parent's constructor. You must call it before usingthis.
Under the Hood
When you call novel.describe(), JavaScript checks the novel object first. It finds no describe there, so it follows the prototype chain to Book.prototype, finds the method there, and calls it. Classes are not a separate mechanism — they are a friendly wrapper over prototypes.
Common Errors
- Forgetting
new:Product('Mug', 12)withoutnewcauses an error. Always create class instances withnew. - Using
thisbefore callingsuper()in a child constructor — this throws an error.
diagram mermaid caption: The prototype chain for a Book instance alt: A flowchart showing novel pointing to Book.prototype, which points to Product.prototype, which points to null. classDiagram novel --> Bookprototype : looks up methods Bookprototype --> Productprototype : inherits from Productprototype --> Null : end of chain
callout tip When to use a class: if you find yourself writing several objects with the same properties and methods, put that shape in a class instead. callout
Exercise
What does this refer to inside mug.describe()?
Show answer
It refers to mug, the object that the method was called on.
Exercise
Why do mug and pen share one describe method instead of each having a copy?
Show answer
Methods live on the class's prototype, which all instances share. This saves memory and means fixing the method once fixes it for every instance.
Spotted a mistake, or code that does not work?