extends in JavaScript: inheriting from an existing class

extends makes one class inherit from another: the child class receives the parent methods, can replace them and can add new ones of its own.
3 min read
Believemy logo

Two classes sharing eighty percent of their code create a familiar problem: every fix has to be made twice, and one of the two always ends up forgotten.

extends is the language answer to that situation. It establishes a lineage between two classes, so that shared code is written only once.


Definition

extends places a class underneath another one. The child class automatically receives the parent methods, can redefine the ones that must change, and can add new ones.

JAVASCRIPT
class User {
  constructor(name) { this.name = name; }
  greet() { return "Hello " + this.name; }
}

class Admin extends User {
  greet() { return super.greet() + " (admin)"; }
  remove(target) { return this.name + " removes " + target; }
}

const admin = new Admin("Camille");
console.log(admin.greet());           // Hello Camille (admin)
console.log(admin instanceof User);   // true

The Admin class has no constructor: the parent one applies as it is. Its greet method replaces the parent version while still reusing it through super. And an admin remains a user in the eyes of instanceof, which means it can be passed anywhere a user is expected.


What the child class receives

Inheritance covers more than people imagine.

What is inheritedDetail
The parent methodsAvailable directly on the instance
The get and set accessorsOn the same footing as methods
The static membersReachable on the child class itself
The constructorOnly when the child declares none

Private fields of the parent, on the other hand, stay out of reach: a child class cannot read a hash-prefixed field declared above it. Exposing internal data to descendants requires an accessor.


Inheriting from built-in classes

The keyword works with the classes of the language, and the most useful case by far is Error.

JAVASCRIPT
class HttpError extends Error {
  constructor(status) {
    super("Request refused with code " + status);
    this.name = "HttpError";
    this.status = status;
  }
}

const error = new HttpError(404);
console.log(error instanceof Error);   // true
console.log(error.status);             // 404

The catching block can then sort errors by type instead of comparing messages. The same mechanism applies to Array or Map, although the need arises far less often there.

Good to know

A child class that declares its own constructor must call super() before using this. Without that call the language raises an error at construction time: the object does not exist yet.


Frequently asked questions

Question

Can a class inherit from several parents?

No, JavaScript allows a single parent per class. When several independent behaviors have to be combined, the usual answer is to write functions that enrich a class and apply them one after another.


Question

How many levels can be stacked?

The language sets no limit, experience does. Beyond two levels, working out where a method comes from means opening three files, and a change in the root class ripples down to descendants you can no longer see. Two levels cover almost every real need.


Question

Inheritance or composition?

Ask what the link really is: inheritance says an object is a variety of another, composition says an object holds another and hands work to it. When the answer hesitates, composition ages better, because it can be swapped without touching the rest. Keep extends for families of types that are genuinely stable.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.