The extends keyword is used in class declarations or class expressions to create a class that is a child of another class.

Try it


class ChildClass extends ParentClass { /* … */ }


The extends keyword can be used to subclass custom classes as well as built-in objects.

Any constructor that can be called with new (which means it must have the prototype property) can be the candidate for the parent class.

function OldStyleClass() {
  this.someProperty = 1;
OldStyleClass.prototype.someMethod = function () {};

class ChildClass extends OldStyleClass {}

class ModernClass {
  someProperty = 1;
  someMethod() {}

class AnotherChildClass extends ModernClass {}

The prototype of the ParentClass must be an Object or null.

function ParentClass() {}
ParentClass.prototype = 3;

class ChildClass extends ParentClass {}
// Uncaught TypeError: Class extends value does not have valid prototype property 3

Note: You would rarely worry about this in practice, because a non-object prototype doesn't behave as it should anyway. (It's ignored by the new operator.)

function ParentClass() {}
ParentClass.prototype = 3;
console.log(Object.getPrototypeOf(new ParentClass()));
// [Object: null prototype] {}
// Not actually a number!

extends will set the prototype for both ChildClass and ChildClass.prototype.

class ParentClass {}
class ChildClass extends ParentClass {}

// Allows inheritance of static properties
Object.getPrototypeOf(ChildClass) === ParentClass;
// Allows inheritance of instance properties
Object.getPrototypeOf(ChildClass.prototype) === ParentClass.prototype;

The right-hand side of extends does not have to be an identifier. You can use any expression that evaluates to a constructor.

class SomeClass extends class {
  constructor() {
    console.log("Base class");
} {
  constructor() {
    console.log("Derived class");

new SomeClass();
// Base class
// Derived class

This is often useful to create mixins.

While the base class may return anything from its constructor, the derived class must return an object or undefined, or a TypeError will be thrown.

class ParentClass {
  constructor() {
    return 1;

console.log(new ParentClass()); // ParentClass {}
// The return value is ignored because it's not an object
// This is consistent with function constructors

class ChildClass extends ParentClass {
  constructor() {
    return 1;

console.log(new ChildClass()); // TypeError: Derived constructors may only return object or undefined

If the parent class constructor returns an object, that object will be used as the this value for the derived class when further initializing class fields. This trick is called "return overriding", which allows a derived class's fields (including private ones) to be defined on unrelated objects.


Using extends

The first example creates a class called Square from a class called Polygon. This example is extracted from this live demo (source).

class Square extends Polygon {
  constructor(length) {
    // Here, it calls the parent class' constructor with lengths
    // provided for the Polygon's width and height
    super(length, length);
    // Note: In derived classes, super() must be called before you
    // can use 'this'. Leaving this out will cause a reference error.
    this.name = 'Square';

  get area() {
    return this.height * this.width;

Using extends with built-in objects

This example extends the built-in Date object. This example is extracted from this live demo (source).

class myDate extends Date {
  getFormattedDate() {
    const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    return `${this.getDate()}-${months[this.getMonth()]}-${this.getFullYear()}`;


ECMAScript Language Specification
# sec-class-definitions

Browser compatibility

BCD tables only load in the browser

See also