Listo (Ctrl + Enter para ejecutar) Bootcamp Fullstack »
app.js
Tab = 4 espacios
1
class BilleteraDigital {
    // 1. Declaración obligatoria de Campos Privados (#)
    #saldo = 0;
    #pin;
    #historialTransacciones = [];

    constructor(titular, saldoInicial, pin) {
        this.titular = titular; // Propiedad pública
        this.#saldo = Math.max(0, saldoInicial);
        this.#pin = String(pin);
        this.#registrarEvento(`Cuenta creada con saldo inicial de $${this.#saldo}`);
    }

    // 2. Método Privado (Solo utilizable dentro de la clase)
    #registrarEvento(descripcion) {
        this.#historialTransacciones.push({
            fecha: new Date().toLocaleTimeString(),
            detalle: descripcion
        });
    }

    #verificarPin(pinIngresado) {
        return String(pinIngresado) === this.#pin;
    }

    // 3. Getter Público: Permite leer el saldo sin permitir alterarlo directamente
    get saldo() {
        return `$${this.#saldo.toFixed(2)}`;
    }

    // 4. Métodos Públicos Seguros
    depositar(monto) {
        if (monto <= 0) {
            console.warn("⚠️ El monto a depositar debe ser mayor a 0.");
            return;
        }
        this.#saldo += monto;
        this.#registrarEvento(`Depósito de +$${monto.toFixed(2)}`);
        console.log(` Depósito exitoso. Nuevo saldo disponible: ${this.saldo}`);
    }

    transferir(monto, cuentaDestino, pinIngresado) {
        if (!this.#verificarPin(pinIngresado)) {
            console.error("⛔ PIN de seguridad incorrecto. Operación bloqueada.");
            return false;
        }

        if (monto > this.#saldo) {
            console.error(`❌ Fondos insuficientes. Intentas transferir $${monto} pero tienes ${this.saldo}`);
            return false;
        }

        this.#saldo -= monto;
        this.#registrarEvento(`Transferencia a [${cuentaDestino}] de -$${monto.toFixed(2)}`);
        console.log(` Transferencia de $${monto.toFixed(2)} a ${cuentaDestino} completada con éxito.`);
        return true;
    }

    verHistorial(pinIngresado) {
        if (!this.#verificarPin(pinIngresado)) {
            console.error("⛔ Acceso denegado al historial.");
            return;
        }
        console.log(`\n=== HISTORIAL DE ${this.titular.toUpperCase()} ===`);
        this.#historialTransacciones.forEach(t => console.log(`• [${t.fecha}] ${t.detalle}`));
    }
}

// ==========================================
// PRUEBA EN EL SANDBOX
// ==========================================
const miBilletera = new BilleteraDigital("Valeria Torres", 500, "1234");

console.log(`Titular público: ${miBilletera.titular}`);
console.log(`Saldo inicial (vía getter): ${miBilletera.saldo}`);

console.log("\n--- OPERACIONES CONTROLADAS ---");
miBilletera.depositar(200);
miBilletera.transferir(150, "Carlos Mendoza", "9999"); // Error de PIN
miBilletera.transferir(150, "Carlos Mendoza", "1234"); // PIN Correcto

miBilletera.verHistorial("1234");

// DEMOSTRACIÓN DE BLINDAJE PRIVADO:
// Intento de hackear el saldo desde fuera:
// miBilletera.#saldo = 999999; // ❌ Descomentar esto causa: SyntaxError: Private field '#saldo' must be declared in an enclosing class
Haz clic para editar este código
Vista Previa
Consola Virtual JavaScript