Há um artigo no MDN Docs sobre 'extends' no JavaScript, e eu quero que explique esse artigo:

extends

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
js
Copy to Clipboard
class ChildClass extends ParentClass { /* … */ }
ParentClass
An expression that evaluates to a constructor function (including a class) or null.

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 and has the prototype property can be the candidate for the parent class. The two conditions must both hold — for example, bound functions and Proxy can be constructed, but they don't have a prototype property, so they cannot be subclassed.

js
Copy to Clipboard
function OldStyleClass() {
  this.someProperty = 1;
}
OldStyleClass.prototype.someMethod = function () {};

class ChildClass extends OldStyleClass {}

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

class AnotherChildClass extends ModernClass {}
The prototype property of the ParentClass must be an Object or null, but 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.)

js
Copy to Clipboard
function ParentClass() {}
ParentClass.prototype = 3;

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

console.log(Object.getPrototypeOf(new ParentClass()));
// [Object: null prototype] {}
// Not actually a number!
extends sets the prototype for both ChildClass and ChildClass.prototype.

Prototype of ChildClass	Prototype of ChildClass.prototype
extends clause absent	Function.prototype	Object.prototype
extends null	Function.prototype	null
extends ParentClass	ParentClass	ParentClass.prototype
js
Copy to Clipboard
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. This is often useful to create mixins. The this value in the extends expression is the this surrounding the class definition, and referring to the class's name is a ReferenceError because the class is not initialized yet. await and yield work as expected in this expression.

js
Copy to Clipboard
class SomeClass extends class {
  constructor() {
    console.log("Base class");
  }
} {
  constructor() {
    super();
    console.log("Derived class");
  }
}

new SomeClass();
// Base class
// Derived class
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.

js
Copy to Clipboard
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() {
    super();
    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.

Subclassing built-ins
Warning: The standard committee now holds the position that the built-in subclassing mechanism in previous spec versions is over-engineered and causes non-negligible performance and security impacts. New built-in methods consider less about subclasses, and engine implementers are investigating whether to remove certain subclassing mechanisms. Consider using composition instead of inheritance when enhancing built-ins.

Here are some things you may expect when extending a class:

When calling a static factory method (like Promise.resolve() or Array.from()) on a subclass, the returned instance is always an instance of the subclass.
When calling an instance method that returns a new instance (like Promise.prototype.then() or Array.prototype.map()) on a subclass, the returned instance is always an instance of the subclass.
Instance methods try to delegate to a minimal set of primitive methods where possible. For example, for a subclass of Promise, overriding then() automatically causes the behavior of catch() to change; or for a subclass of Map, overriding set() automatically causes the behavior of the Map() constructor to change.
However, the above expectations take non-trivial efforts to implement properly.

The first one requires the static method to read the value of this to get the constructor for constructing the returned instance. This means [p1, p2, p3].map(Promise.resolve) throws an error because the this inside Promise.resolve is undefined. A way to fix this is to fall back to the base class if this is not a constructor, like Array.from() does, but that still means the base class is special-cased.
The second one requires the instance method to read this.constructor to get the constructor function. However, new this.constructor() may break legacy code, because the constructor property is both writable and configurable and is not protected in any way. Therefore, many copying built-in methods use the constructor's [Symbol.species] property instead (which by default just returns this, the constructor itself). However, [Symbol.species] allows running arbitrary code and creating instances of arbitrary type, which poses a security concern and greatly complicates subclassing semantics.
The third one leads to visible invocations of custom code, which makes a lot of optimizations harder to implement. For example, if the Map() constructor is called with an iterable of x elements, then it must visibly invoke the set() method x times, instead of just copying the elements into the internal storage.
These problems are not unique to built-in classes. For your own classes, you will likely have to make the same decisions. However, for built-in classes, optimizability and security are a much bigger concern. New built-in methods always construct the base class and call as few custom methods as possible. If you want to subclass built-ins while achieving the above expectations, you need to override all methods that have the default behavior baked into them. Any addition of new methods on the base class may also break the semantics of your subclass because they are inherited by default. Therefore, a better way to extend built-ins is to use composition.

Mas, lembre dessas regras:

O que eu gostaria que você soubesse sobre mim para obter respostas melhores:

1 - Não consigo entender palavras difíceis.
2 - Sou iniciante no mundo da tecnologia.

O que eu gostaria que você respondesse:

1  - Você deve sempre ser detalhista em qualquer tipo de informação que eu pedir, independente se possa ser respondido com 1 linha, precisa ser detalhista, mas não podemos utilizar palavras difíceis para não dificultar a leitura.

2 - Você deve ser imparcial em tudo o que disser.

3 - A conversa precisa ser amigável, então não é pra conversar com um tom muito sério.

4 - Não assuma que sei de alguma coisa, pense que se você introduzir algum conceito diferente, é provavel que eu não saiba.
5 - Não elimine informação do artigo na sua resposta, não faça um tipo de resumo, tudo que eles forem apresentar no artigo como informação, deve ser explicado, só que mais fácil.