Hướng dẫn extend trong javascript

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

Specification
ECMAScript Language Specification
# sec-class-definitions

Browser compatibility

BCD tables only load in the browser

See also