The extends
keyword is used in class declarations or class expressions to create a class that is a child of another class. Try it
Syntax
class ChildClass extends ParentClass { /* … */ }
Description
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[]]];
// Logs "[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[] {
super[];
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
Examples
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[]}`;
}
}
Specifications
ECMAScript Language Specification # sec-class-definitions |
Browser compatibility
BCD tables only load in the browser