JavaScript inheritance and overriding
Reuse initialization and specialize instance behavior.
On this page
Classes, constructors, and this.
- Reuse initialization and specialize instance behavior.
- Predict the sample output and explain the state changes.
- Complete the practice task and check the boundary cases.
The concept
extends connects a subclass to a superclass. A derived constructor must call super before using this so the base initialization can run.
Overriding a method changes behavior for subclass instances. A loop can call the same method on different compatible objects.
Code example
class Animal {
constructor(name) { this.name = name; }
speak() { return this.name + ": sound"; }
}
class Dog extends Animal {
constructor(name) { super(name); }
speak() { return this.name + ": woof"; }
}
for (const animal of [new Animal("Milo"), new Dog("Rex")]) {
console.log(animal.speak());
}Milo: sound Rex: woof
Follow the code
Open the walkthrough to inspect the example one step at a time.
Show guided walkthrough
class Animal { constructor(name) { this.name = name; } speak() { return this.name + ": sound"; }}class Dog extends Animal { constructor(name) { super(name); } speak() { return this.name + ": woof"; }}for (const animal of [new Animal("Milo"), new Dog("Rex")]) { console.log(animal.speak());}Follow the example
Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.
View the complete dry-run table
| Step / line | What happens | State after step | Output so far |
|---|---|---|---|
| Initialize Milo through Animal and Rex through the super call. | objects: Animal(name=Milo), Dog(name=Rex) | — | |
| The first object uses Animal.speak. | return = Milo: sound | — | |
| Print the first result. | return = Milo: sound | Milo: sound | |
| The Dog object uses its override. | return = Rex: woof | Milo: sound | |
| Print the second result. | return = Rex: woof | Milo: sound Rex: woof |
Behind the scenes
How JavaScript processes this code
A JavaScript engine parses and runs the source. A function body runs when the function is called. console.log writes to the console.
Cost and common mistakes
O(n) calls for n objects, plus the cost of constructing each output string.
- Use super before this in an explicit derived constructor.
- Private # fields belong to their declaring class and are not directly accessible in a subclass.
Try it yourself
Create Cat extending Animal and override speak to append ': meow'.
Reveal answer and reasoning
A Cat('Luna') in the loop prints Luna: meow without changing the loop body.