Domina la Programación Orientada a Objetos en JavaScript con clases modernas, herencia prototípica y patrones avanzados. Esta guía práctica te enseñará a estructurar código complejo usando los principios de POO en ES6+.
Diagrama de clases y herencia en JavaScript
Contenido del Artículo
Clases ES6: Fundamentos
Sintaxis moderna para crear objetos:
Constructor
Método especial para inicialización
Métodos
Funciones definidas en la clase
Palabra clave 'new'
Crear instancias de objetos
// Definición de clase básica
class Persona {
constructor(nombre, edad) {
this.nombre = nombre;
this.edad = edad;
}
saludar() {
console.log(`Hola, soy ${this.nombre}`);
}
// Método estático
static compararEdades(personaA, personaB) {
return personaA.edad - personaB.edad;
}
}
// Crear instancia
const juan = new Persona('Juan', 30);
juan.saludar(); // Hola, soy Juan
// Llamar método estático
const maria = new Persona('María', 25);
Persona.compararEdades(juan, maria); // 5
Herencia y Polimorfismo
Extender clases y sobrescribir métodos:
// Clase base
class Animal {
constructor(nombre) {
this.nombre = nombre;
}
hacerSonido() {
console.log('Sonido genérico');
}
}
// Subclase
class Perro extends Animal {
constructor(nombre, raza) {
super(nombre); // Llamar constructor padre
this.raza = raza;
}
// Sobrescribir método
hacerSonido() {
console.log('¡Guau guau!');
}
// Nuevo método específico
ladrar() {
this.hacerSonido();
}
}
// Uso
const miPerro = new Perro('Rex', 'Labrador');
miPerro.hacerSonido(); // ¡Guau guau!
miPerro.ladrar(); // ¡Guau guau!
super se usa para acceder a métodos y propiedades de la clase padre
Encapsulamiento: Campos Privados
Proteger datos internos con campos privados:
class CuentaBancaria {
// Campos privados (prefijados con #)
#saldo;
#pin;
constructor(titular, saldoInicial, pin) {
this.titular = titular;
this.#saldo = saldoInicial;
this.#pin = pin;
}
// Método público para acceder a saldo
getSaldo(pin) {
if (pin === this.#pin) {
return this.#saldo;
}
throw new Error('PIN incorrecto');
}
depositar(cantidad) {
if (cantidad > 0) {
this.#saldo += cantidad;
}
}
retirar(cantidad, pin) {
if (pin !== this.#pin) {
throw new Error('PIN incorrecto');
}
if (cantidad > 0 && cantidad <= this.#saldo) {
this.#saldo -= cantidad;
return cantidad;
}
throw new Error('Fondos insuficientes');
}
}
// Uso
const cuenta = new CuentaBancaria('Ana', 1000, '1234');
console.log(cuenta.getSaldo('1234')); // 1000
cuenta.depositar(500);
console.log(cuenta.getSaldo('1234')); // 1500
cuenta.retirar(200, '1234');
console.log(cuenta.getSaldo('1234')); // 1300
Los campos privados (#nombre) son una característica de ES2022
Patrones Avanzados POO
Técnicas profesionales para diseño orientado a objetos:
// Factory Method
class Producto {
constructor(nombre, precio) {
this.nombre = nombre;
this.precio = precio;
}
}
class ProductoFactory {
crearLibro(nombre, precio, autor) {
const libro = new Producto(nombre, precio);
libro.autor = autor;
libro.tipo = 'libro';
return libro;
}
crearElectronico(nombre, precio, marca) {
const electronico = new Producto(nombre, precio);
electronico.marca = marca;
electronico.tipo = 'electronico';
return electronico;
}
}
// Uso
const factory = new ProductoFactory();
const libro = factory.crearLibro('JavaScript POO', 29.99, 'Carlos Pérez');
const laptop = factory.crearElectronico('Laptop Pro', 1200, 'TechBrand');
// Singleton
class Configuracion {
static instancia;
constructor() {
if (Configuracion.instancia) {
return Configuracion.instancia;
}
this.apiUrl = 'https://api.ejemplo.com';
this.modoDebug = false;
Configuracion.instancia = this;
}
}
// Siempre misma instancia
const config1 = new Configuracion();
const config2 = new Configuracion();
console.log(config1 === config2); // true
Patrón | Implementación | Caso de uso |
---|---|---|
Singleton | Clase con una instancia global | Configuración, Logging |
Factory | Método que crea objetos | Creación compleja de objetos |
Decorator | Añadir funcionalidad dinámica | Extender objetos sin herencia |
Strategy | Intercambiar algoritmos | Validación, Procesamiento |