CodeForge

JavaScript de Cero a Experto / POO en JS

Getters, setters y static

Teoría20 min20 XP

Tres refinamientos separan una clase básica de una clase con oficio: propiedades que se CALCULAN al leerlas (getters), asignaciones que se VIGILAN (setters), y utilidades que pertenecen al molde y no a las instancias (static). Los tres existen en cada librería que usarás — hoy aprendes a leerlos y a escribirlos.

get: el tablero del carro

La alternativa — mantener this.total como número y acordarte de actualizarlo en cada agregar — es un bug esperando fecha: algún camino del código olvidará la actualización. Regla de diseño: lo que se puede DERIVAR de otros datos, no se guarda: se calcula. (Guárdala bien: es uno de los principios centrales de React y compañía.)

set: la válvula con filtro

Un setter intercepta la ASIGNACIÓN: por fuera parece objeto.propiedad = valor, por dentro corre tu función — el lugar perfecto para validar:

setter.js
class Bolsillo {
// ...

set presupuesto(valor) {
  // la aduana: nada inválido entra
  if (typeof valor !== "number" || valor <= 0) {
    throw new Error("El presupuesto debe ser un número mayor que cero");
  }
  this._presupuesto = valor;   // el dato real, con guion bajo
}

get presupuesto() {
  return this._presupuesto ?? 0;
}
}

const b = new Bolsillo("Sara");
b.presupuesto = 500000;     // pasa por la aduana ✓
b.presupuesto = -100;       // ✗ throw: asignación rechazada

El detalle del _presupuesto: el setter necesita guardar el dato en OTRA propiedad (si hiciera this.presupuesto = valor se llamaría a sí mismo en un bucle infinito). El guion bajo es la convención histórica para "esto es interno, no lo toques"… pero es solo cortesía: b._presupuesto = -100 sigue entrando por la puerta de atrás. El candado de verdad llega en la próxima lección.

static: el teléfono de la fábrica

Un miembro static pertenece al MOLDE, no a las tazas: se llama Clase.metodo(), sin instancia. Sus dos usos estrella — fábricas alternativas y utilidades del dominio:

Dentro de un static, this es la CLASE (no hay instancia) — por eso su territorio natural es lo que no depende de un objeto concreto. Y el remate: Object.keys, JSON.parse, Number.isNaN, Math.max… medio lenguaje que ya dominas son métodos estáticos. Otra maquinaria que pisabas sin mirarla.

Tu clase guarda this.total actualizándolo a mano en agregar() y en eliminar(). Un compañero agrega el método descontar() y olvida tocar el total: ahora la app muestra cifras viejas. ¿Cuál es el arreglo de fondo?

Mini-reto

Refina tu Bolsillo: 1) getter promedio (total / cantidad, cuidando la división por cero con un ternario); 2) setter titular que rechace con throw strings vacíos (usa _titular por dentro y su getter de salida); 3) static Bolsillo.combinar(b1, b2) que fabrique un bolsillo nuevo con los movimientos de ambos (spread del módulo 5). Pruébalo todo, incluido el try/catch del titular inválido.

Qué sigue

El _presupuesto con guion bajo quedó protegido por pura cortesía — cualquiera puede saltárselo. La próxima lección instala el candado real: campos privados con #, invisibles e intocables desde afuera. La encapsulación deja de ser una promesa y se vuelve ley.