Class Inheritance
Learn how to share behavior between classes using extends and super, override inherited methods, call a parent method from a child, and understand the prototype chain behind it all.
Reading Time
18 min
Lesson
Lesson 40 of 48
Why Inheritance?
Inheritance lets one class reuse the properties and methods of another, so you don't have to duplicate shared logic across multiple similar classes. If you have several kinds of things that are all fundamentally the same but with a few differences — say, different kinds of Animal, or different kinds of Employee — you can put the shared behavior in a base class and let more specific classes build on top of it, adding or overriding only what's different.
The extends Keyword
The extends keyword is placed after a class name to indicate it inherits from another class. The class doing the inheriting is usually called the child, subclass, or derived class; the class being inherited from is the parent, superclass, or base class. Every instance method and property defined on the parent becomes available to instances of the child, without having to be rewritten.
A Basic extends Example
Console Output
Click “Run” to see the console output here.
super() in Constructors
When a subclass defines its own constructor, it must call super(...) before it can use this — super() calls the parent class's constructor, which is what actually creates and initializes the instance. Skipping this call, or trying to use this before calling it, throws a ReferenceError. Whatever arguments the parent constructor expects should be passed through super(...).
Calling super() in a Subclass Constructor
Console Output
Click “Run” to see the console output here.
Forgetting super() Throws an Error
If a subclass defines a constructor, JavaScript requires super() to be called before this is accessed anywhere inside that constructor. Forgetting it entirely — not just referencing this too early — produces: ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor.
Overriding Methods
A subclass can override an inherited method simply by defining a method with the same name. When that method is called on an instance of the subclass, JavaScript uses the subclass's version instead of the parent's — this is normal method overriding, and it's how different subclasses can customize shared behavior while keeping the same method name.
Overriding an Inherited Method
Console Output
Click “Run” to see the console output here.
Calling the Parent's Version with super.methodName()
Sometimes you don't want to fully replace a parent's method — you want to extend it, running the parent's original logic and then adding something extra. Inside an overriding method, super.methodName() calls the parent class's version of that same method, letting you build on top of it instead of duplicating its logic.
Extending a Method with super.speak()
Console Output
Click “Run” to see the console output here.
The Prototype Chain, Briefly
When you write class Dog extends Animal, JavaScript links Dog.prototype's internal prototype to Animal.prototype. So when you call rex.speak() and Dog.prototype doesn't have a speak() method, the JavaScript engine walks up this chain — from rex, to Dog.prototype, to Animal.prototype — until it finds one. This chain of linked prototypes is exactly what makes inheritance work, and extends is simply a convenient way of wiring it up for you.
Inspecting the Prototype Chain
Console Output
Click “Run” to see the console output here.
Checking Inheritance with instanceof
The instanceof operator checks whether an object exists anywhere along a particular constructor’s prototype chain, returning true or false. An instance of a subclass is an instanceof both the subclass and every class it inherits from, all the way up the chain.
instanceof Across the Chain
Console Output
Click “Run” to see the console output here.
Rules to Remember About Inheritance
- extends links a subclass to a parent class, inheriting its methods
- super() must be called in a subclass constructor before using this
- A method with the same name in a subclass overrides the parent’s version
- super.methodName() lets you call the parent’s version explicitly
- instanceof checks membership anywhere along the prototype chain
Favor Composition When Inheritance Gets Deep
A single level of inheritance (a subclass extending one parent) is usually easy to reason about. Long inheritance chains — subclasses of subclasses of subclasses — tend to become fragile and hard to trace. If you find yourself several levels deep, it’s often worth reconsidering whether composing smaller, focused objects together would be simpler than continuing to extend.