CodeForge

JavaScript de Cero a Experto / POO en JS

Herencia: extends, super e instanceof

Teoría20 min20 XP

"Mi Bolsillo" registra gastos… y también ingresos. Ambos tienen nombre, valor y fecha; cada uno tiene lo suyo. Escribir dos clases casi idénticas sería volver al copy-paste de la lección 1 — la herencia lo resuelve: una clase BASE con lo común, y clases hijas que la extienden.

El modelo base y sus versiones

Las piezas, una por una: extends conecta el molde hijo al padre (un eslabón más en la cadena de prototipos — cuando sueldo.resumen() no existiera en Ingreso, se buscaría en Movimiento). super(...) DENTRO del constructor hijo llama al constructor del padre — y es obligatorio ANTES de tocar this: primero se construye la base del carro, luego se instala el techo corredizo. Y super.metodo() invoca la versión del padre desde un override: redefines sin duplicar.

instanceof: preguntar el linaje

objeto instanceof Clase responde si el objeto salió de ese molde o de cualquiera que lo extienda — técnicamente, si Clase.prototype está en su cadena. Su uso típico: ramificar comportamiento cuando llegan movimientos mezclados:

clasificar.js
const movimientos = [arriendo, sueldo, new Gasto("Café", 4500, "comida")];

const gastado = movimientos
.filter((m) => m instanceof Gasto)
.reduce((acum, g) => acum + g.valor, 0);

¿Te suena de otra parte? Ya lo habías usado sin saberlo: error.name === "AbortError" del módulo 10 era la versión artesanal de esta pregunta — los errores de JavaScript son, de hecho, una jerarquía de clases (TypeError extends Error), y en el módulo 15 crearás la tuya.

Nota honesta: la herencia se usa POCO y en capas de a una

La herencia brilla cuando la relación es un "ES UN" clarísimo y estable (un gasto ES un movimiento, un TypeError ES un Error). Pero las jerarquías profundas — nieta extiende hija extiende madre extiende abuela — se vuelven rígidas: un cambio arriba sacude todo el árbol, y los casos reales nunca encajan tan limpio. La industria llegó a un lema que oirás mil veces: composición sobre herencia — antes que un árbol genealógico, objetos que TIENEN piezas y funciones que se combinan. Ese estilo es exactamente el módulo 12. Regla práctica mientras tanto: un nivel de extends es útil; si vas por el tercero, replantea.

En el constructor de Gasto escribes this.categoria = categoria ANTES del super(nombre, valor), y JavaScript revienta con 'Must call super constructor before accessing this'. ¿Por qué ese orden es obligatorio?

Mini-reto

Extiende la jerarquía del playground: crea GastoFijo extends Gasto (esos que llegan solos cada mes: arriendo, plan del celular) con una propiedad extra diaDeCobro y un override de resumen() que agregue "(fijo, día N)" reutilizando super.resumen(). Comprueba con instanceof que un GastoFijo es las TRES cosas a la vez (GastoFijo, Gasto, Movimiento)… y siente en carne propia el tercer nivel de la cadena: ¿se está poniendo rígido? Esa incomodidad es la nota honesta de arriba, confirmada con las manos.

Qué sigue

Tus clases ya tienen datos, comportamiento y linaje. Las próximas dos lecciones las profesionalizan: propiedades CALCULADAS que se leen sin paréntesis (getters), validación al asignar (setters), utilidades del molde que no necesitan instancia (static)… y después, el candado de verdad: campos privados.