Herencia entre clases y el uso de extends y super() en JavaScript
Dominar la herencia es dar el salto de escribir código repetitivo a crear arquitecturas robustas y escalables. En esta guía, exploraremos cómo las palabras clave extends y super() actúan como los cimientos que permiten a tus clases comunicarse y compartir lógica de forma eficiente.

Índice
1. ¿Qué es la herencia entre clases?
La herencia entre clases en JavaScript es un mecanismo que permite que una clase (hija) reutilice las propiedades y métodos de otra clase (padre).
Esto significa que una clase puede extender el comportamiento de otra, evitando repetir código y permitiendo construir estructuras más organizadas y escalables.
En otras palabras:
- Clase padre (base) → define comportamiento general.
- Clase hija (derivada) → hereda ese comportamiento y puede usarlo o modificarlo.
Este concepto es fundamental cuando un proyecto crece, porque permite crear arquitecturas reutilizables.
CONCEPTO padre–hijo
La relación funciona así:
ClasePadre
↑
ClaseHija
La clase hija hereda todo lo público de la clase padre.
Esto incluye:
- propiedades
- métodos
- lógica reutilizable
RECUERDA! – El prototipo por detrás:
Aunque usamos la sintaxis de class (introducida en ES6), es importante recordar que JavaScript sigue usando herencia prototípica. Las clases son «azúcar sintáctico»; por debajo, el motor de JS conecta los prototipos de los objetos para que puedan buscar métodos en la cadena de mando.
1.1. Ejemplo simple de herencia
Supongamos que tenemos una clase base que representa un componente del DOM.
// --- CLASE PADRE ----
class ComponenteUI {
constructor(elemento) {
// Guardamos una referencia a un elemento del DOM
this.elemento = elemento
}
// Método que muestra el elemento
mostrar() {
// Cambia el display del elemento
this.elemento.style.display = "block"
}
// Método que oculta el elemento
ocultar() {
// Oculta el elemento
this.elemento.style.display = "none"
}
}Lenguaje del código: JavaScript (javascript)
¿Qué representa esta clase?
Esta clase define comportamientos comunes para elementos del DOM, como:
- mostrar
- ocultar
Ahora podemos crear otras clases más específicas.
📌AHORA CREAMOS UNA CLASE HIJA CON extends
// --- CLASE HIJA ---- Que hereda de ComponenteUI
class Modal extends ComponenteUI {
abrir() {
// usamos el método heredado de la clase padre
this.mostrar()
console.log("Modal abierto")
}
cerrar() {
// usamos el método heredado
this.ocultar()
console.log("Modal cerrado")
}
}Lenguaje del código: JavaScript (javascript)
Qué ocurre aquí
La clase Modal hereda automáticamente de la clase padre, la clase ComponenteUI. (para ello usamos extends – ampliaremos -):
mostrar()
ocultar()
elemento
1.1.1. Uso real en el DOM
Supongamos que tenemos este HTML:
<div id="modal">Contenido del modal</div>Lenguaje del código: HTML, XML (xml)
Ahora lo usamos con nuestras clases.
// seleccionamos el elemento del DOM
const modalElemento = document.getElementById("modal")
// creamos una instancia de la clase Modal
const modal = new Modal(modalElemento)
// abrimos el modal
modal.abrir()
// cerramos el modal
modal.cerrar()Lenguaje del código: JavaScript (javascript)
Qué sucede aquí
Modalhereda la lógica deComponenteUI- reutiliza los métodos
mostrar()yocultar() - agrega su propia lógica (
abrirycerrar)
Esto evita repetir código.
1.2. Idea clave que debes recordar de este punto
La herencia permite que:
- Una clase especializad – Herede comportamiento – De una clase más general
Ejemplo conceptual:
ComponenteUI
↑
Modal
↑
ModalLogin
Cada nivel hereda y especializa comportamiento.
EN RESUMEN:
La herencia entre clases en JavaScript permite que una clase hija reutilice propiedades y métodos de una clase padre mediante extends. Esto se usa en proyectos reales para crear componentes reutilizables del DOM, organizar la arquitectura del código y evitar duplicación de lógica.
2. extends
2.1. ¿Qué es extends en JavaScript?
extends es una palabra clave de JavaScript que se usa para crear una clase hija a partir de una clase padre.
Permite que la nueva clase herede propiedades y métodos de la clase base.
Esto forma una relación llamada herencia.
2.2. Sintaxis general de extends
La sintaxis básica es la siguiente:
class ClasePadre {
// propiedades y métodos generales
}
class ClaseHija extends ClasePadre {
// propiedades y métodos específicos
}Lenguaje del código: JavaScript (javascript)
Aquí ocurre lo siguiente:
ClaseHijahereda todo lo público deClasePadreClaseHijapuede usar esos métodos directamente
2.3. Ejemplo simple paso a paso
Primero creamos una clase padre.
// Clase padre
class Animal {
constructor(nombre) {
// Guardamos el nombre del animal
this.nombre = nombre
}
// Método que describe una acción
hacerSonido() {
console.log("El animal hace un sonido")
}
}Lenguaje del código: JavaScript (javascript)
Qué tiene esta clase
- Propiedad:
nombre - Método:
hacerSonido()
Ahora creamos una clase hija usando extends.
// Clase hija que hereda de Animal
class Perro extends Animal {
ladrar() {
// método propio de la clase Perro
console.log(this.nombre + " está ladrando")
}
}Lenguaje del código: JavaScript (javascript)
Qué ocurre aquí
Perro hereda automáticamente de Animal:
nombre
hacerSonido()
Y además tiene su propio método:
ladrar()
2.3.1. Uso de la clase hija
Ahora creamos un objeto de la clase Perro.
// Creamos una instancia de la clase Perro
const miPerro = new Perro("Rex")
// usamos el método heredado de la clase padre
miPerro.hacerSonido()
// RESULTADO: El animal hace un sonido
// usamos el método propio de la clase hija
miPerro.ladrar()
// RESULTADO: Rex está ladrandoLenguaje del código: JavaScript (javascript)
¿Qué pasó internamente?
Cuando usamos:
class Perro extends AnimalLenguaje del código: JavaScript (javascript)
JavaScript crea una relación de herencia como esta:
Perro
↓
Animal
Entonces cuando hacemos:
miPerro.hacerSonido()Lenguaje del código: CSS (css)
JavaScript busca el método en este orden:
objeto miPerro
↓
Perro.prototype
↓
Animal.prototypeLenguaje del código: CSS (css)
Si lo encuentra en la cadena, lo ejecuta.
Esto se llama cadena prototípica.
2.4. ¿Qué hereda una clase hija cuando usamos extends?
Esto incluye principalmente:
- Métodos definidos en el
prototypede la clase padre - La estructura del constructor (cuando se usa con
super()) - Acceso a las propiedades que inicializa la clase padre
Esto permite reutilizar lógica sin duplicar código.
3. super()
3.1. ¿Qué es super() en JavaScript?
super es una herramienta dual. Dependiendo de cómo la uses (como una función o como un objeto), te da acceso a diferentes partes del padre:
- Para heredar las propiedades del padre (Como función)
- Para llamar a un método que existe en el padre (Como objeto)
✅En este punto nos centraremos para heredar las propiedades del padre
En otras palabras, super() permite que la clase hija inicialice las propiedades que pertenecen a la clase padre.
Cuando usamos herencia:
class Hija extends PadreLenguaje del código: JavaScript (javascript)
la clase hija debe ejecutar primero el constructor del padre para que el objeto se cree correctamente.
Para eso se usa: super()
3.2. Qué hace realmente super()
Cuando se ejecuta super() ocurre lo siguiente:
- Se ejecuta el constructor de la clase padre
- Se inicializan las propiedades definidas en el padre
- Se crea correctamente el objeto (
this) - El flujo vuelve al constructor de la clase hija
3.3. ¿Como usar super() para heredar propiedades?
Teniendo en mente su sintaxis:
super(argumento1, argumento2, ...)
Se utiliza únicamente dentro del constructor de la clase hija. Su función es llamar al constructor de la clase padre y enviarle los datos que necesita para inicializarse.
Reglas de oro para su uso correcto:
- Debe ser la primera línea:
- No puedes usar
thisantes de llamar asuper().
- No puedes usar
- Correspondencia:
- Los argumentos que pongas dentro de
super()deben coincidir con lo que el constructor del padre espera recibir.
- Los argumentos que pongas dentro de
3.4. Ejemplo sencillo
Imagina que tenemos una clase base Empleado que solo guarda el nombre, y una clase Vendedor que además necesita guardar cuánto ha vendido.
// CLASE PADRE
class Empleado {
// Aquí el constructor espera recibir 1 argumento (nombre)
constructor(nombre) {
this.nombre = nombre; // El padre sabe cómo guardar el nombre
}
}
// CLASE HIJA
class Vendedor extends Empleado {
constructor(nombre, ventasTotales) {
// PASO 1: Le enviamos el 'nombre' al argumento del padre para que él lo gestione
super(nombre);
// PASO 2: Ahora el hijo guarda lo que le es propio
this.ventasTotales = ventasTotales;
}
mostrarInfo() {
console.log(`${this.nombre} ha vendido $${this.ventasTotales}.`);
}
}
const miVendedor = new Vendedor("Ana", 5000);
miVendedor.mostrarInfo(); // Salida: Ana ha vendido $5000.
Lenguaje del código: JavaScript (javascript)
Explicación del Proceso
constructor(nombre, ventasTotales):- El
Vendedorrecibe dos datos cuando lo creas connew.
- El
super(nombre): Aquí es donde ocurre la magia. ElVendedorle dice alEmpleado: «Oye, toma este nombre y guárdalo tú, que tú ya sabes cómo hacerlo».- Esto ejecuta el código
this.nombre = nombreque está definido en la clase padre.
- Esto ejecuta el código
this.ventasTotales = ventasTotales:- Una vez que el padre terminó su trabajo, el hijo puede seguir con sus propias propiedades únicas.
¿Qué pasa si olvidas el argumento?
Si escribes solo super(), el constructor del padre se ejecutará, pero el nombre será undefined, porque no le pasaste la información necesaria.
3.5. ¿Por qué super() es obligatorio?
En una clase hija no se puede usar this hasta que el constructor del padre haya sido ejecutado.
Esto ocurre porque la clase padre es la responsable de inicializar el objeto base.
Por eso JavaScript exige que super() se ejecute primero.
3.6. Error común: usar this antes de super()
Este código es incorrecto.
class Estudiante extends Persona {
constructor(nombre, curso) {
// ❌ ERROR
this.curso = curso
// el constructor del padre aún no se ejecutó
super(nombre)
}
}Lenguaje del código: JavaScript (javascript)
JavaScript lanzará un error como:
ReferenceError:
Must call super constructor before using 'this'Lenguaje del código: JavaScript (javascript)
Esto ocurre porque el objeto aún no ha sido inicializado por el padre.
✅IDEA CLAVE QUE DEBEMOS RECORDAR SOBRE super()
super() sirve para:
- Ejecutar el constructor del padre
- Inicializar propiedades heredadas
- Crear correctamente el objeto (this)
Sin super(): La clase hija no puede usar this
4. super.metodo()
4.1. ¿Qué es super.metodo() en JavaScript?
super.metodo() es una forma de acceder y ejecutar un MÉTODO definido en la clase padre desde una clase hija.
Se usa principalmente cuando:
- Queremos reutilizar la lógica del método del padre
- Queremos extender ese comportamiento en la clase hija
En otras palabras:
super.metodo() → ejecuta el método que está en la clase padre
4.2. Diferencia entre super() y super.metodo()
Es importante no confundirlos.
| Uso | Función |
|---|---|
super() | ejecuta el constructor de la clase padre |
super.metodo() | ejecuta un método del padre |
Ejemplo conceptual:
super() // constructor del padre
super.saludar() // método del padreLenguaje del código: JavaScript (javascript)
4.3. Ejemplo básico
1️⃣Primero creamos una clase padre.
// Clase padre
class Persona {
constructor(nombre) {
// propiedad que guarda el nombre
this.nombre = nombre
}
saludar() {
console.log("Hola, soy " + this.nombre)
}
}Lenguaje del código: JavaScript (javascript)
Esta clase tiene:
propiedad → nombre
método → saludar()
2️⃣Ahora creamos una clase hija que usa super.metodo()
// Clase hija que hereda de Persona
class Estudiante extends Persona {
constructor(nombre, curso) {
// ejecuta el constructor del padre
super(nombre)
// propiedad propia del estudiante
this.curso = curso
}
saludar() {
// usamos el método de la clase padre
super.saludar()
// agregamos comportamiento adicional
console.log("Estoy estudiando " + this.curso)
}
}Lenguaje del código: JavaScript (javascript)
¿Qué está pasando en este código?
El método saludar() existe en el padre, pero en la clase hija lo sobrescribimos.
Dentro de ese método hacemos:
super.saludar()Lenguaje del código: JavaScript (javascript)
Eso ejecuta el método original del padre.
Luego agregamos comportamiento nuevo.
3️⃣Uso del código
// creamos una instancia
const alumno = new Estudiante("Laura", "JavaScript")
// llamamos al método saludar
alumno.saludar()Lenguaje del código: JavaScript (javascript)
Resultado:
Hola, soy Laura
Estoy estudiando JavaScript
✅Primero se ejecuta el método del padre y luego el del hijo.
5. El polimorfismo
5.1. ¿Qué es el polimorfismo?
El polimorfismo es uno de los pilares de la programación orientada a objetos. Su nombre viene del griego «muchas formas».
En JavaScript, se refiere a la capacidad de que diferentes clases tengan un método con el mismo nombre, pero que cada una lo ejecute de una manera distinta.
5.2. ¿Cómo funciona en JavaScript?
En JS, el polimorfismo suele ocurrir a través de la herencia. Una clase padre define un método general, y las clases hijas lo «sobrescriben» para darle su propio comportamiento.
Lo más potente es que puedes tratar a diferentes objetos de forma uniforme (llamar al mismo método) sin preocuparte de qué tipo exacto son.
5.3. Ejemplo simple con clases
5.3.1. Primero creamos una clase base.
// Clase base
class Animal {
sonido() {
// comportamiento general
console.log("El animal hace un sonido")
}
}Lenguaje del código: JavaScript (javascript)
Esta clase define un método llamado:
sonido()
5.3.2. Crear clases hijas con comportamientos distintos
Ahora creamos distintas clases que heredan de Animal.
// Clase hija Perro
class Perro extends Animal {
sonido() {
// sobrescribimos el método sonido()
console.log("El perro ladra")
}
}
// Clase hija Gato
class Gato extends Animal {
sonido() {
// mismo método, comportamiento diferente
console.log("El gato maúlla")
}
}
// Clase hija Pájaro
class Pajaro extends Animal {
sonido() {
console.log("El pájaro canta")
}
}Lenguaje del código: JavaScript (javascript)
Todas tienen el mismo método:
sonido()
Pero cada clase lo implementa de manera distinta.
5.3.3. Creamos objetos
// creamos distintos objetos
const perro = new Perro()
const gato = new Gato()
const pajaro = new Pajaro()Lenguaje del código: JavaScript (javascript)
5.3.4. Ejecutar el mismo método en distintos objetos
// llamamos al mismo método en distintos objetos
perro.sonido()
gato.sonido()
pajaro.sonido()Lenguaje del código: JavaScript (javascript)
Resultado:
El perro ladra
El gato maúlla
El pájaro canta
Aquí vemos claramente el polimorfismo.
El método es el mismo:
sonido()
Pero el comportamiento cambia según el objeto.
5.3.5. Ejemplo clásico de polimorfismo
Podemos usar un array de objetos distintos y ejecutar el mismo método.
// creamos un array con distintos animales
const animales = [
new Perro(),
new Gato(),
new Pajaro()
]
// recorremos el array
animales.forEach(animal => {
// llamamos al mismo método
animal.sonido()
})Lenguaje del código: JavaScript (javascript)
Resultado:
El perro ladra
El gato maúlla
El pájaro canta
La función no necesita saber qué tipo de objeto es.
Solo sabe que tiene un método:
sonido()
5.4. ¿Por qué es importante?
- Flexibilidad:
- Puedes añadir una nueva clase (por ejemplo,
Vaca) con su propiosonido()y el resto de tu código seguirá funcionando sin cambiar ni una sola línea.
- Puedes añadir una nueva clase (por ejemplo,
- Simplicidad:
- No necesitas llenar tu código de
if (esPerro)oif (esGato). Simplemente llamas al método y dejas que el objeto se encargue.
- No necesitas llenar tu código de
- Desacoplamiento:
- Tu programa principal no necesita conocer los detalles internos de cada clase, solo necesita saber qué «mensajes» (métodos) pueden recibir.
