Volver al curso

JavaScript Desde Cero: Tu Primer Lenguaje de Programación

leccion
6 / 22
beginner
8 horas
Control de Flujo y Funciones

Condicionales: if, else if, else y switch

Lectura
40 min~10 min lectura

Condicionales: if, else if, else y switch

Objetivos de aprendizaje

Al finalizar esta lección serás capaz de:

  • Escribir condicionales con if, else if y else para tomar decisiones en tu código
  • Utilizar switch para comparaciones con múltiples opciones
  • Combinar condiciones con operadores lógicos (&&, ||, !)
  • Aplicar patrones comunes de condicionales en situaciones reales
  • Evitar los errores más frecuentes al escribir condicionales

1. La estructura if: tomando decisiones

La programación consiste fundamentalmente en tomar decisiones. "Si el usuario tiene 18 años o más, dejarlo entrar. Si no, mostrar un mensaje de error." Esta capacidad de elegir qué código ejecutar según una condición es lo que hace a los programas inteligentes.

La estructura if es la herramienta más básica y poderosa para tomar decisiones en JavaScript.

Sintaxis básica

if (condicion) {
  // Este código se ejecuta SOLO si la condición es true
}

La condición entre paréntesis se evalúa como true o false. Si es true, el bloque de código dentro de las llaves se ejecuta. Si es false, se salta por completo.

const edad = 20;

if (edad >= 18) {
  console.log("Sos mayor de edad. Podés entrar.");
}
// Output: "Sos mayor de edad. Podés entrar."

const temperatura = 35;

if (temperatura > 30) {
  console.log("Hace mucho calor. Tomá agua.");
  console.log(`La temperatura actual es ${temperatura}°C`);
}

if...else: dos caminos

Cuando necesitás ejecutar código alternativo si la condición es false:

const hora = 14;

if (hora < 12) {
  console.log("¡Buenos días!");
} else {
  console.log("¡Buenas tardes!");
}
// Output: "¡Buenas tardes!"

// Ejemplo práctico: verificar stock
const stock = 0;

if (stock > 0) {
  console.log(`Disponible. Quedan ${stock} unidades.`);
} else {
  console.log("Producto agotado. Te notificamos cuando vuelva.");
}

if...else if...else: múltiples condiciones

Cuando hay más de dos posibilidades:

const nota = 85;

if (nota >= 90) {
  console.log("Calificación: Excelente (A)");
} else if (nota >= 80) {
  console.log("Calificación: Muy Bueno (B)");
} else if (nota >= 70) {
  console.log("Calificación: Bueno (C)");
} else if (nota >= 60) {
  console.log("Calificación: Regular (D)");
} else {
  console.log("Calificación: Insuficiente (F)");
}
// Output: "Calificación: Muy Bueno (B)"

Importante: JavaScript evalúa las condiciones de arriba a abajo y ejecuta el PRIMER bloque cuya condición sea true. Después salta al final de toda la estructura.

// ⚠️ Error de principiante: orden incorrecto
const precio = 150;

// ❌ MAL: la primera condición atrapa todo
if (precio > 0) {
  console.log("Precio normal");
} else if (precio > 100) {
  console.log("Precio alto"); // ¡Nunca se ejecuta!
}

// ✅ BIEN: condiciones de más específica a menos específica
if (precio > 100) {
  console.log("Precio alto");
} else if (precio > 0) {
  console.log("Precio normal");
}

Combinando condiciones con operadores lógicos

const edad = 25;
const tieneLicencia = true;
const tieneMultas = false;

// AND (&&): TODAS las condiciones deben cumplirse
if (edad >= 18 && tieneLicencia && !tieneMultas) {
  console.log("Podés conducir");
}

// OR (||): Al menos UNA condición debe cumplirse
const diaSemana = "sábado";
if (diaSemana === "sábado" || diaSemana === "domingo") {
  console.log("¡Es fin de semana!");
}

// Combinaciones complejas
const usuario = { edad: 30, plan: "premium", pais: "AR" };

if ((usuario.plan === "premium" || usuario.plan === "enterprise") && usuario.edad >= 18) {
  console.log("Acceso completo habilitado");
}

// NOT (!): Negar una condición
const estaLogueado = false;
if (!estaLogueado) {
  console.log("Por favor, iniciá sesión");
}

Condicionales anidados

Podés poner un if dentro de otro, aunque hay que tener cuidado con la legibilidad:

const usuario = { nombre: "Ana", edad: 25, suscripcion: "premium" };

// ❌ Demasiado anidado (difícil de leer)
if (usuario) {
  if (usuario.edad >= 18) {
    if (usuario.suscripcion === "premium") {
      console.log("Acceso completo");
    } else {
      console.log("Acceso básico");
    }
  } else {
    console.log("Menor de edad");
  }
}

// ✅ Guard clauses (retorno temprano - más limpio)
function verificarAcceso(usuario) {
  if (!usuario) return "Usuario no válido";
  if (usuario.edad < 18) return "Menor de edad";
  if (usuario.suscripcion !== "premium") return "Acceso básico";
  return "Acceso completo";
}

console.log(verificarAcceso(usuario)); // "Acceso completo"

El patrón de guard clauses (retornos tempranos) es preferido por desarrolladores profesionales porque reduce la anidación y hace el código más legible.


2. La estructura switch: comparaciones múltiples

Cuando necesitás comparar una variable con muchos valores posibles, switch puede ser más limpio que una cadena de else if:

const diaSemana = "miércoles";

switch (diaSemana) {
  case "lunes":
    console.log("Inicio de semana. ¡Fuerza!");
    break;
  case "martes":
  case "miércoles":
  case "jueves":
    console.log("Mitad de semana. ¡Seguí así!");
    break;
  case "viernes":
    console.log("¡Viernes! Casi fin de semana.");
    break;
  case "sábado":
  case "domingo":
    console.log("¡Fin de semana! A descansar.");
    break;
  default:
    console.log("Día no reconocido");
}
// Output: "Mitad de semana. ¡Seguí así!"

El temido break olvidado (fall-through)

Si olvidás el break, JavaScript sigue ejecutando los siguientes case sin verificar la condición. Esto se llama "fall-through" y es una fuente común de bugs:

const fruta = "manzana";

// ❌ Sin break — fall-through bug
switch (fruta) {
  case "manzana":
    console.log("Es una manzana"); // Se ejecuta
  case "banana":
    console.log("Es una banana");  // ¡También se ejecuta!
  case "cereza":
    console.log("Es una cereza");  // ¡También se ejecuta!
}
// Output:
// "Es una manzana"
// "Es una banana"
// "Es una cereza"

Ejemplo práctico: calculadora de envío

function calcularEnvio(zona, peso) {
  let costoBase;
  
  switch (zona) {
    case "local":
      costoBase = 200;
      break;
    case "provincial":
      costoBase = 500;
      break;
    case "nacional":
      costoBase = 900;
      break;
    case "internacional":
      costoBase = 2500;
      break;
    default:
      return { error: `Zona "${zona}" no reconocida` };
  }
  
  // Agregar costo por peso extra (más de 1 kg)
  const costoExtra = peso > 1 ? (peso - 1) * 150 : 0;
  const total = costoBase + costoExtra;
  
  return {
    zona,
    peso: `${peso} kg`,
    costoBase: `$${costoBase}`,
    costoExtra: `$${costoExtra}`,
    total: `$${total}`
  };
}

console.table(calcularEnvio("nacional", 3));

¿if-else o switch?

Situación Usar
Comparar UNA variable con valores exactos switch
Evaluar rangos (>, <, >=, <=) if-else
Condiciones complejas con && y || if-else
Muchos valores posibles de un mismo dato switch
2-3 condiciones simples if-else

3. Patrones avanzados de condicionales

El operador ternario como alternativa compacta

Ya lo vimos en el módulo anterior, pero vale profundizar su uso con condicionales:

// En vez de:
let mensaje;
if (edad >= 18) {
  mensaje = "Adulto";
} else {
  mensaje = "Menor";
}

// Podés escribir:
const mensaje = edad >= 18 ? "Adulto" : "Menor";

// Útil para asignaciones condicionales
const descuento = esMiembroVIP ? 0.20 : 0.05;
const saludo = hora < 12 ? "Buenos días" : hora < 18 ? "Buenas tardes" : "Buenas noches";

// Útil en template literals
console.log(`Tenés ${items} item${items !== 1 ? "s" : ""} en el carrito`);

// Útil en JSX (React)
// <p>{estaLogueado ? "Bienvenido" : "Iniciá sesión"}</p>

Objetos como lookup tables (alternativa elegante a switch)

// En vez de un switch largo:
function obtenerPrecioSwitch(plan) {
  switch (plan) {
    case "basic": return 9.99;
    case "pro": return 19.99;
    case "enterprise": return 49.99;
    default: return 0;
  }
}

// Podés usar un objeto como tabla de búsqueda:
const PRECIOS = {
  basic: 9.99,
  pro: 19.99,
  enterprise: 49.99
};

function obtenerPrecio(plan) {
  return PRECIOS[plan] ?? 0; // nullish coalescing para el default
}

console.log(obtenerPrecio("pro")); // 19.99
console.log(obtenerPrecio("ultra")); // 0

// Esto es especialmente útil con funciones:
const ACCIONES = {
  crear: () => console.log("Creando..."),
  editar: () => console.log("Editando..."),
  eliminar: () => console.log("Eliminando..."),
};

const accion = "editar";
(ACCIONES[accion] ?? (() => console.log("Acción no encontrada")))();

Validaciones encadenadas

function validarRegistro(datos) {
  const errores = [];
  
  if (!datos.nombre || datos.nombre.trim().length < 2) {
    errores.push("El nombre debe tener al menos 2 caracteres");
  }
  
  if (!datos.email || !datos.email.includes("@")) {
    errores.push("El email no es válido");
  }
  
  if (!datos.password || datos.password.length < 8) {
    errores.push("La contraseña debe tener al menos 8 caracteres");
  }
  
  if (datos.password && !/[A-Z]/.test(datos.password)) {
    errores.push("La contraseña debe incluir al menos una mayúscula");
  }
  
  if (datos.password && !/[0-9]/.test(datos.password)) {
    errores.push("La contraseña debe incluir al menos un número");
  }
  
  if (datos.edad !== undefined && (datos.edad < 13 || datos.edad > 120)) {
    errores.push("La edad debe estar entre 13 y 120 años");
  }
  
  return {
    esValido: errores.length === 0,
    errores
  };
}

// Probar
const resultado = validarRegistro({
  nombre: "A",
  email: "correo-invalido",
  password: "1234",
  edad: 10
});

console.log(resultado.esValido); // false
console.table(resultado.errores);
// [
//   "El nombre debe tener al menos 2 caracteres",
//   "El email no es válido",
//   "La contraseña debe tener al menos 8 caracteres",
//   "La contraseña debe incluir al menos una mayúscula",
//   "La edad debe estar entre 13 y 120 años"
// ]

Errores comunes de principiantes
  1. Usar = en vez de === en la condición: if (x = 5) es una asignación (siempre true), if (x === 5) es una comparación.

  2. Olvidar break en switch: Sin break, el código "cae" al siguiente case. Usá break en cada case.

  3. Orden incorrecto en else if: Poné las condiciones más específicas primero y las más generales al final.

  4. Condicionales demasiado anidados: Más de 2-3 niveles de anidación es señal de que necesitás refactorizar. Usá guard clauses o funciones auxiliares.

  5. No considerar todos los casos: Siempre incluí un else o default para manejar situaciones inesperadas.


Puntos clave de esta lección
  1. if-else es la estructura fundamental para tomar decisiones — evalúa condiciones de arriba a abajo.
  2. else if permite encadenar múltiples condiciones — la primera que sea true se ejecuta.
  3. switch es ideal cuando comparás UNA variable con múltiples valores exactos.
  4. Siempre incluí break en cada case del switch para evitar fall-through.
  5. Los guard clauses (retornos tempranos) son más limpios que condicionales anidados.
  6. Los objetos como lookup tables son una alternativa elegante al switch para mapeos simples.
  7. Ordená las condiciones de más específica a más general para evitar que condiciones amplias atrapen todo.

Quiz de autoevaluación

1. ¿Qué pasa si olvidás el break en un case de switch?
a) Da un error de sintaxis
b) El código sigue ejecutando los cases siguientes (fall-through)
c) Solo se ejecuta ese case
d) El programa se detiene

2. ¿Cuál es la salida de if (0) { console.log('A') } else { console.log('B') }?
a) A
b) B
c) Error
d) Nada

3. ¿Qué son las guard clauses?
a) Funciones de seguridad
b) Retornos tempranos que evitan anidación excesiva
c) Un tipo de loop
d) Validaciones de HTML

4. ¿Cuándo es preferible usar switch sobre if-else?
a) Siempre
b) Cuando evaluás rangos numéricos
c) Cuando comparás una variable con múltiples valores exactos
d) Cuando hay condiciones complejas con &&

5. ¿Qué operador usamos para negar una condición?
a) &&
b) ||
c) !
d) !!

Respuestas: 1-b, 2-b, 3-b, 4-c, 5-c


💡 Concepto Clave

Revisemos los puntos más importantes de esta lección antes de continuar.

Ejercicio práctico

Misión: Sistema de descuentos de una tienda online

Creá una función calcularPrecioFinal(producto, usuario) que:

  1. Reciba un objeto producto con { nombre, precio, categoria } y un objeto usuario con { tipo, edad, esPrimeraCompra }
  2. Aplique descuentos según estas reglas:
    • Miembros VIP: 15% de descuento
    • Estudiantes (edad < 25): 10% de descuento
    • Primera compra: 5% extra
    • Si la categoría es "liquidación": 20% adicional
    • Los descuentos se acumulan (se aplican uno después del otro)
  3. Use guard clauses para validar que los datos sean correctos
  4. Retorne un objeto con el precio original, cada descuento aplicado y el precio final
const producto = { nombre: "Zapatillas Nike", precio: 15000, categoria: "deportes" };
const usuario = { tipo: "vip", edad: 22, esPrimeraCompra: true };
console.log(calcularPrecioFinal(producto, usuario));
🧠 Pon a prueba tu conocimiento
¿Cuál es el aspecto más importante que aprendiste en esta lección?
  • Comprendo el concepto principal y puedo explicarlo con mis palabras
  • Entiendo cómo aplicarlo en mi situación específica
  • Necesito repasar algunas partes antes de continuar
  • Quiero ver más ejemplos prácticos del tema
✅ ¡Excelente! Continúa con la siguiente lección para profundizar más.