One Class Building on Another
Inheritance lets a class start from another class's blueprint and extend it. You get every field and method of the parent for free, and can add or change whatever you need:
Dog extends Animal means: "a Dog is an Animal, plus a bit more." rex has no speak method of its own, but the lookup falls through to Animal, which does. That fallthrough is the whole mechanism — it's just prototype chaining with nicer syntax.
super in the Constructor
A subclass with its own constructor has one hard rule: call super(...) before touching this. super runs the parent's constructor, which is what actually creates and initialises the object:
Skip the super(name) line and you'll get a ReferenceError the moment you try to read or write this. The engine simply refuses to give you a this until the parent has had its turn.
If a subclass doesn't declare its own constructor, JavaScript generates one that forwards all arguments to super — so you only need to write one when you're adding fields or doing extra setup.
Overriding Methods
A subclass can redefine any method it inherits. The nearest one on the chain wins:
No magic here — when you call speak() on a Dog, the engine looks for speak on the instance, then on Dog.prototype, finds it, and stops. It never gets to Animal.prototype.
Extending, Not Replacing: super.method()
Sometimes you don't want to replace the parent's method — you want to add to it. super.method(...) calls the parent's version from inside the override:
This is where inheritance earns its keep: the subclass reuses the parent's logic instead of copying it. If Animal.describe changes later, Dog.describe picks up the change for free.
super works in any method, not just the constructor. It always refers to the parent class's version of whatever you're calling.
instanceof and the Chain
instanceof checks whether an object's prototype chain includes a given class. Every subclass instance is also an instance of its parents:
All four are true. The chain goes Puppy -> Dog -> Animal -> Object, and instanceof walks it. Useful for type checks, though in practice you'll lean on it less than you'd think — most code just calls methods and lets polymorphism handle the rest.
A Slightly Bigger Example
A common pattern: a base class with shared logic, and a couple of subclasses that specialise it.
Notice describe lives on Shape and never needs to be rewritten — it just calls this.area(), which resolves to the right subclass at runtime. That's polymorphism: the same call site, different behavior based on the actual object.
Inheritance vs Composition
Inheritance is tempting because it feels productive — one line gets you a pile of methods. It ages badly when hierarchies grow.
Rule of thumb: use extends when the relationship is clearly "X is a Y" and the subclass genuinely shares most of the parent's behavior. When you're reaching for inheritance just to share a helper method or two, prefer composition — give the class a field that holds the helper object:
Deep inheritance trees (Animal -> Mammal -> Dog -> WorkingDog -> PoliceDog) look neat in diagrams and get painful in code — a change near the root ripples unpredictably through every descendant. Most healthy codebases stay one or two levels deep and lean on composition for the rest.
Next: Static Members
Everything in this doc lives on instances — methods you call via new Thing().something(). Sometimes you want methods or data that belong to the class itself, not any particular instance. That's what static is for, and it's up next.
Frequently Asked Questions
How does inheritance work in JavaScript?
One class can inherit from another using extends. The subclass gets every method and field of the parent, and can add its own or override existing ones. Under the hood, JavaScript links the subclass's prototype to the parent's prototype, so method lookups fall through automatically.
What does super do in JavaScript?
super(...) calls the parent class's constructor — you must call it before using this in a subclass constructor. super.method(...) calls the parent's version of a method, which is how you extend behavior rather than replace it entirely.
Should I use inheritance or composition in JavaScript?
Use inheritance when there's a genuine 'is-a' relationship and the subclass shares most of the parent's behavior. Reach for composition — objects holding other objects — when you just want to share functionality. Deep class hierarchies tend to age badly; most real codebases stay one or two levels deep.