JavaScript inheritance and overriding

Reuse initialization and specialize instance behavior.

JavaScript
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());
}
Output
Milo: sound
Rex: woof

Explanation

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.

Explore the dry run
Guided walkthroughReady
1class Animal {
2 constructor(name) { this.name = name; }
3 speak() { return this.name + ": sound"; }
4}
5class Dog extends Animal {
6 constructor(name) { super(name); }
7 speak() { return this.name + ": woof"; }
8}
9for (const animal of [new Animal("Milo"), new Dog("Rex")]) {
10 console.log(animal.speak());
11}

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
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput 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

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.

Further reading