Programación Orientada a Objetos (POO) en JavaScript
JavaScript no nació como un lenguaje orientado a objetos en el sentido clásico. Por debajo de las clases que usamos hoy sigue funcionando un sistema de prototipos, y entender esa base ayuda a escribir código más predecible.
Clases: la cara visible
Desde ES6, JavaScript permite declarar clases con una sintaxis familiar para quien viene de otros lenguajes:
class Vehiculo {
constructor(marca) {
this.marca = marca;
}
describir() {
return `Este vehículo es un ${this.marca}`;
}
}
const coche = new Vehiculo('Toyota');
console.log(coche.describir());
Esto parece programación orientada a objetos "de manual". Pero por dentro, sigue siendo prototipos.
Prototipos: lo que hay debajo
Cada objeto en JavaScript tiene una referencia interna a otro objeto, su prototipo, del que hereda propiedades y métodos. Cuando accedes a una propiedad que un objeto no tiene directamente, JavaScript la busca en la cadena de prototipos.
console.log(coche.__proto__ === Vehiculo.prototype); // true
Esto explica por qué todos los objetos creados con new Vehiculo() comparten el mismo método describir sin duplicarlo en memoria: viven una sola vez en el prototipo.
Herencia con extends
La herencia entre clases usa extends, que en realidad conecta las cadenas de prototipos por debajo:
class Coche extends Vehiculo {
constructor(marca, puertas) {
super(marca);
this.puertas = puertas;
}
}
super() llama al constructor de la clase padre antes de añadir las propiedades propias de Coche.
Por qué importa
Entender que las clases son una capa de sintaxis sobre los prototipos evita sorpresas: por ejemplo, por qué modificar Vehiculo.prototype afecta a instancias ya creadas, o por qué ciertos patrones de composición funcionan distinto a como se esperaría en un lenguaje puramente basado en clases.