CodeForge

JavaScript de Cero a Experto / Patrones y observables

Singleton: el único ejemplar

Teoría18 min20 XP

Hay piezas de una app que DEBEN ser únicas: la configuración, la conexión al servidor, el carrito del usuario. Dos copias descoordinadas = bugs bizarros. El patrón singleton garantiza el ejemplar único — y en JavaScript moderno tiene un secreto encantador: los módulos ya te lo regalan.

El acueducto del barrio

El singleton gratis: un módulo con estado

La lección pasada lo dejó dicho: un módulo se evalúa UNA vez y se cachea — todos los que lo importan comparten LO MISMO. Entonces un singleton en JavaScript moderno es simplemente… un módulo que exporta la instancia:

Sigue la prueba: pantalla-a y pantalla-b importan sesion.js cada una por su lado… y el log de construcción sale UNA vez, y el cambio que hace A lo ve B. No hay dos sesiones: hay un acueducto y dos llaves. Este patrón — módulo con estado privado + funciones de acceso exportadas — es el singleton idiomático de JavaScript, y lo usarás para configuración, cachés, el cliente de tu API…

La versión con clase (la verás por ahí)

Antes de ESM, el patrón se hacía a mano con una clase que se guarda a sí misma:

singleton-clasico.js
class Sesion {
static #instancia = null;   // el único ejemplar, guardado en el molde

static obtener() {
  if (Sesion.#instancia === null) Sesion.#instancia = new Sesion();
  return Sesion.#instancia;   // siempre EL MISMO objeto
}
}

Sesion.obtener() === Sesion.obtener();   // true

Léela y admira las piezas del módulo 11 trabajando juntas (static + campo privado + construcción perezosa)… y luego guárdala como cultura: en código moderno, el módulo hace esto con cero ceremonia. Si te la piden en entrevista, la sabes escribir; en tu código, exporta desde un módulo.

Nota honesta de arquitecto: el singleton tiene mala fama merecida cuando se vuelve el cajón GLOBAL donde todo el mundo lee y escribe de todo — eso acopla la app entera a un punto y hace los tests un infierno (el módulo 16 te lo mostrará). Regla de oro: pocas cosas merecen ser únicas, y las que lo sean exponen una API mínima (funciones), no el objeto crudo mutable.

El archivo carrito.js exporta funciones sobre un array privado de productos. Lo importan la página de tienda y la de pago. ¿Cuántos carritos existen y por qué?

Mini-reto

Construye el singleton de "Mi Bolsillo": un bolsillo.js con array privado de gastos y exports agregar(nombre, valor) (con validación que lanza, módulo 11) y total(). Impórtalo desde dos módulos "pantalla" — uno agrega, el otro consulta — y comprueba en index.js que ambos trabajan sobre el mismo bolsillo. Remate mental: ¿qué exportarías (y qué JAMÁS) para que nadie pueda meter un gasto sin validar?

Qué sigue

El singleton garantiza UN ejemplar. El patrón opuesto — fabricar MUCHOS, a pedido y con variantes — también tiene nombre: factory. Ya la usaste sin saberlo dos módulos seguidos; la próxima lección la formaliza y te da el criterio factory vs clase.