Encontré un ejemplo de MDN sobre super. Aprendí que la superfunción llama al constructor de los padres para que la subclase pueda heredar todas las propiedades/métodos de ella. Sin embargo, en el ejemplo de MDn, llama al constructor de la subclase.
<script> class Rectangle { constructor(height, width) { this.name = 'Rectangle'; this.height = height; this.width = width; } } class Square extends Rectangle { constructor(length) { super(length, length); this.name = 'Square'; } } let a = new Square(4); console.log(JSON.stringify(a)); console.log(a.height); </script>Entonces tenemos un constructor Square que se extiende desde Rectangle. Mi confusión está en la super función que tiene dos argumentos de Square pero Square es la subclase de Rectangle. ¿No tendría sentido llamar a super dentro de Square y pasarle la altura y el ancho de Rectangle para que Square pueda heredar la altura y el ancho de Rectangle ya que Square está extendiendo a Rectangle?
La herencia ocurre automáticamente, no necesita llamar a super() para esto.
super() se usa para ejecutar el constructor de la clase principal. Cuando llamas a new Square(4) , esto llama al constructor Square automáticamente con length = 4 . Pero el constructor Rectangle requiere dos parámetros, no los mismos parámetros que el constructor Square . El diseño de Square es que es un rectángulo cuya altura y ancho son iguales, por lo que el constructor de Square puede pasar este parámetro de length a Rectangle para expresar esta idea.
No podemos ir a la inversa, porque una clase puede tener muchas subclases diferentes, y cada una de ellas puede tener relaciones diferentes con ella. No hay forma de que la superclase llame a todos los constructores de subclases posibles, ya que las subclases se pueden agregar arbitrariamente.
en el ejemplo de MDN, llama al constructor de la subclase.
No, no lo hace.
¿No tendría sentido llamar a
superdentro deSquare[…] para queSquarepueda heredar la altura y el ancho deRectangleya queSquareestá extendiendoRectangle?
Eso es exactamente lo que está pasando.
… y pasar la altura y el ancho de
Rectanglea él
pequeña aclaración: está pasando un valor (la longitud del lado cuadrado) como alto y ancho a Rectangle .
La new Square llama a la new Rectangle .
Square es una clase derivada de Rectangle. El constructor Square llama al constructor de la clase Rectangle padre pasando la longitud del Square como el ancho y la altura del Rectangle. Tiene sentido hacer esto porque un cuadrado es un rectángulo, pero es un tipo específico de rectángulo, es decir, uno cuyo ancho es igual a su altura.
Tenga en cuenta que Square es más específico que Rectangle y Rectangle no sabe nada sobre Square.
El constructor Square existe porque Square es una especialización de Rectangle. Un cuadrado tiene longitud (por ejemplo, dibújame un cuadrado de longitud 5). También tiene un nombre diferente ('Cuadrado' frente a 'Rectángulo'). Eso significa que la clase Square necesita un constructor, para que pueda inicializar las cosas que son especiales sobre un Square.
Debido a que necesita un constructor Square, ese constructor Square debe llamar al (super) constructor Rectangle y debe hacerlo antes de acceder a 'this' (lo que hace cuando establece el nombre del cuadrado) o regresar desde el constructor derivado. Este es un requisito del lenguaje JavaScript. Si no llama al superconstructor, su código fallará: ocurrirá un ReferenceError, así:
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructorSi no necesitara hacer ninguna inicialización especial en el constructor de una clase derivada, entonces ni siquiera necesitaría declarar una función constructora en la clase derivada. En este caso, JavaScript llamaría automáticamente al constructor de la clase principal al crear una instancia de la clase derivada. Pero, si declarara una función constructora en la clase derivada, incluso si estuviera vacía, tendría que llamar al superconstructor, de lo contrario, ocurriría el ReferenceError antes mencionado.