Switch case
Introducción
La estructura switch
es una alternativa a múltiples declaraciones if/else
cuando necesitamos comparar una variable con diferentes valores. Esta estructura de control nos permite evaluar una expresión contra varios casos posibles y ejecutar el bloque de código correspondiente al caso que coincida. El switch case
resulta especialmente útil cuando tenemos múltiples condiciones basadas en el valor de una misma variable, haciendo que nuestro código sea más organizado, legible y, en algunos casos, más eficiente.
Sintaxis de la estructura switch
La sintaxis básica de la estructura switch
es la siguiente:
switch (expresion) {
case valor1:
// Código a ejecutar si expresion === valor1
break;
case valor2:
// Código a ejecutar si expresion === valor2
break;
// Más casos según sea necesario
default:
// Código a ejecutar si ninguno de los casos coincide
}
Los elementos principales de esta estructura son:
- expresion: La variable o expresión que se va a evaluar
- case valorN: Cada uno de los posibles valores que puede tener la expresión
- break: Sentencia que termina la ejecución del bloque
switch
- default: Bloque opcional que se ejecuta si ningún caso coincide
Veamos un ejemplo básico:
const diaSemana = 3;
let nombreDia;
switch (diaSemana) {
case 1:
nombreDia = "Lunes";
break;
case 2:
nombreDia = "Martes";
break;
case 3:
nombreDia = "Miércoles";
break;
case 4:
nombreDia = "Jueves";
break;
case 5:
nombreDia = "Viernes";
break;
case 6:
nombreDia = "Sábado";
break;
case 7:
nombreDia = "Domingo";
break;
default:
nombreDia = "Día no válido";
}
console.log(nombreDia); // Muestra: "Miércoles"
En este ejemplo:
- Evaluamos el valor de
diaSemana
(que es 3) - Recorremos los casos hasta encontrar
case 3:
- Ejecutamos el código asociado, asignando "Miércoles" a la variable
nombreDia
- La sentencia
break
nos saca de la estructuraswitch
Comparación con múltiples if/else
Para entender mejor el valor de switch
, veamos el mismo ejemplo implementado con múltiples condiciones if/else
:
const diaSemana = 3;
let nombreDia;
if (diaSemana === 1) {
nombreDia = "Lunes";
} else if (diaSemana === 2) {
nombreDia = "Martes";
} else if (diaSemana === 3) {
nombreDia = "Miércoles";
} else if (diaSemana === 4) {
nombreDia = "Jueves";
} else if (diaSemana === 5) {
nombreDia = "Viernes";
} else if (diaSemana === 6) {
nombreDia = "Sábado";
} else if (diaSemana === 7) {
nombreDia = "Domingo";
} else {
nombreDia = "Día no válido";
}
console.log(nombreDia); // Muestra: "Miércoles"
Como podemos observar, la versión con switch
resulta más clara y estructurada, especialmente cuando tenemos muchos casos posibles basados en un mismo valor.
Cláusulas case y default
Cláusula case
Cada case
representa un valor posible de la expresión evaluada:
- JavaScript utiliza comparación estricta (
===
) entre la expresión y el valor del caso - Después de cada caso, se escribe el código a ejecutar cuando hay coincidencia
- El
break
es fundamental para salir delswitch
una vez ejecutado el código del caso
Cláusula default
La cláusula default
funciona de manera similar al else
en las estructuras condicionales:
const fruta = "Mango";
let mensaje;
switch (fruta) {
case "Manzana":
mensaje = "Las manzanas son rojas o verdes";
break;
case "Plátano":
mensaje = "Los plátanos son amarillos";
break;
case "Naranja":
mensaje = "Las naranjas son anaranjadas";
break;
default:
mensaje = "No conozco el color de esa fruta";
}
console.log(mensaje); // Muestra: "No conozco el color de esa fruta"
En este ejemplo, como ninguno de los casos coincide con "Mango", se ejecuta el código dentro de default
.
Comportamiento del break
La sentencia break
es crucial en la estructura switch
, ya que determina si la ejecución continúa o se detiene:
const opcion = 2;
let resultado = "";
switch (opcion) {
case 1:
resultado += "Opción 1 seleccionada. ";
// Sin break, continúa ejecutando el siguiente caso
case 2:
resultado += "Opción 2 seleccionada. ";
// Sin break, continúa ejecutando el siguiente caso
case 3:
resultado += "Opción 3 seleccionada. ";
break; // Aquí sí hay break, por lo que detiene la ejecución
case 4:
resultado += "Opción 4 seleccionada. ";
break;
default:
resultado += "Opción no válida.";
}
console.log(resultado);
// Muestra: "Opción 2 seleccionada. Opción 3 seleccionada. "
En este ejemplo:
- La expresión coincide con
case 2:
- Como no hay
break
después del caso 2, la ejecución continúa al caso siguiente - Se ejecuta también el código del caso 3
- El
break
en el caso 3 detiene la ejecución, por lo que no se llega al caso 4
Este comportamiento se conoce como "fall-through" (ejecución en cascada).
Agrupación de casos
Una característica útil del switch
es la posibilidad de agrupar varios casos que comparten el mismo código:
const diaSemana = 5; // Viernes
let tipoDeJornada;
switch (diaSemana) {
case 1:
case 2:
case 3:
case 4:
case 5:
tipoDeJornada = "Día laborable";
break;
case 6:
case 7:
tipoDeJornada = "Fin de semana";
break;
default:
tipoDeJornada = "Día no válido";
}
console.log(tipoDeJornada); // Muestra: "Día laborable"
En este ejemplo, los casos del 1 al 5 comparten el mismo código, al igual que los casos 6 y 7. Esta agrupación hace que el código sea más compacto y evita repeticiones innecesarias.
Fall-through (ejecución en cascada)
El "fall-through" o ejecución en cascada ocurre cuando omitimos intencionalmente la sentencia break
para que se ejecuten varios casos consecutivos:
const nivel = 2;
let mensaje = "Tu nivel te permite: ";
switch (nivel) {
case 3:
mensaje += "administrar usuarios, ";
// Cae al caso 2
case 2:
mensaje += "crear contenido, ";
// Cae al caso 1
case 1:
mensaje += "leer artículos.";
break;
default:
mensaje = "No tienes permisos.";
}
console.log(mensaje);
// Muestra: "Tu nivel te permite: crear contenido, leer artículos."
Este patrón es útil cuando queremos que los niveles superiores hereden las capacidades de los niveles inferiores, como en un sistema de permisos.
Casos de uso apropiados
El switch
es particularmente útil en los siguientes escenarios:
1. Menús de opciones
function procesarOpcion(opcion) {
switch (opcion) {
case "nuevo":
return "Creando nuevo archivo...";
case "abrir":
return "Abriendo archivo existente...";
case "guardar":
return "Guardando cambios...";
case "exportar":
return "Exportando archivo...";
case "salir":
return "Cerrando programa...";
default:
return "Opción no reconocida.";
}
}
console.log(procesarOpcion("guardar")); // Muestra: "Guardando cambios..."
2. Estados de un proceso
const estadoPedido = "enviado";
let mensaje;
switch (estadoPedido.toLowerCase()) {
case "procesando":
mensaje = "Tu pedido está siendo preparado.";
break;
case "enviado":
mensaje = "Tu pedido está en camino.";
break;
case "entregado":
mensaje = "Tu pedido ha sido entregado.";
break;
case "cancelado":
mensaje = "Tu pedido ha sido cancelado.";
break;
default:
mensaje = "Estado del pedido desconocido.";
}
console.log(mensaje); // Muestra: "Tu pedido está en camino."
3. Cálculos basados en categorías
function calcularImpuesto(producto, precio) {
let porcentaje;
switch (producto) {
case "alimento":
porcentaje = 4;
break;
case "medicamento":
porcentaje = 4;
break;
case "libro":
porcentaje = 4;
break;
case "ropa":
porcentaje = 21;
break;
case "electronica":
porcentaje = 21;
break;
default:
porcentaje = 10;
}
return precio * (porcentaje / 100);
}
console.log(calcularImpuesto("libro", 20)); // Muestra: 0.8 (4% de 20)
Buenas prácticas y limitaciones
Buenas prácticas:
-
Usar siempre
break
: A menos que específicamente queramos el comportamiento de fall-through, siempre debemos incluirbreak
al final de cada caso. -
Incluir
default
: Aunque es opcional, es una buena práctica incluir siempre un casodefault
para manejar valores inesperados. -
Preferir constantes sobre variables: Para mejorar la legibilidad, es mejor usar valores constantes en los casos.
-
Considerar el uso de objetos: Para casos muy complejos o numerosos, a veces un objeto de mapeo puede ser más eficiente.
// Alternativa a switch con un objeto
const diasSemana = {
1: "Lunes",
2: "Martes",
3: "Miércoles",
4: "Jueves",
5: "Viernes",
6: "Sábado",
7: "Domingo"
};
const dia = diasSemana[3] || "Día no válido";
console.log(dia); // Muestra: "Miércoles"
Limitaciones:
-
Comparación estricta:
switch
usa comparación estricta (===
), lo que puede ser limitante en algunos casos. -
Expresiones limitadas: No es adecuado para comparaciones complejas o de rango.
-
Solo valores concretos: Solo compara con valores específicos, no permite condiciones como "mayor que" o "menor que".
Ejemplos prácticos
Ejemplo 1: Calculadora simple
function calculadora(a, operacion, b) {
let resultado;
switch (operacion) {
case "+":
resultado = a + b;
break;
case "-":
resultado = a - b;
break;
case "*":
resultado = a * b;
break;
case "/":
if (b === 0) {
return "No se puede dividir por cero";
}
resultado = a / b;
break;
default:
return "Operación no válida";
}
return resultado;
}
console.log(calculadora(10, "+", 5)); // Muestra: 15
console.log(calculadora(10, "*", 5)); // Muestra: 50
console.log(calculadora(10, "/", 0)); // Muestra: "No se puede dividir por cero"
Ejemplo 2: Convertidor de meses
function obtenerDiasDelMes(mes, anio) {
let dias;
switch (mes) {
case 1: // Enero
case 3: // Marzo
case 5: // Mayo
case 7: // Julio
case 8: // Agosto
case 10: // Octubre
case 12: // Diciembre
dias = 31;
break;
case 4: // Abril
case 6: // Junio
case 9: // Septiembre
case 11: // Noviembre
dias = 30;
break;
case 2: // Febrero
// Comprobación de año bisiesto
if ((anio % 4 === 0 && anio % 100 !== 0) || anio % 400 === 0) {
dias = 29;
} else {
dias = 28;
}
break;
default:
return "Mes no válido";
}
return dias;
}
console.log(obtenerDiasDelMes(2, 2024)); // Muestra: 29 (2024 es bisiesto)
console.log(obtenerDiasDelMes(2, 2023)); // Muestra: 28
console.log(obtenerDiasDelMes(4, 2023)); // Muestra: 30
Ejemplo 3: Evaluación de calificaciones
function obtenerCalificacion(puntuacion) {
// Aseguramos que puntuacion es un número entre 0 y 100
puntuacion = Math.max(0, Math.min(100, Math.round(puntuacion)));
let letra;
switch (Math.floor(puntuacion / 10)) {
case 10:
case 9:
letra = "A";
break;
case 8:
letra = "B";
break;
case 7:
letra = "C";
break;
case 6:
letra = "D";
break;
default:
letra = "F";
}
return `Puntuación: ${puntuacion}, Calificación: ${letra}`;
}
console.log(obtenerCalificacion(95)); // Muestra: "Puntuación: 95, Calificación: A"
console.log(obtenerCalificacion(81)); // Muestra: "Puntuación: 81, Calificación: B"
console.log(obtenerCalificacion(68)); // Muestra: "Puntuación: 68, Calificación: D"
console.log(obtenerCalificacion(42)); // Muestra: "Puntuación: 42, Calificación: F"
Resumen
La estructura switch
es una herramienta poderosa para manejar múltiples condiciones basadas en una misma expresión. Ofrece una alternativa más clara y organizada que múltiples sentencias if/else
cuando trabajamos con valores específicos y discretos.
Hemos aprendido la sintaxis básica, la importancia de las sentencias break
, el comportamiento de fall-through (ejecución en cascada), y cómo agrupar casos que comparten el mismo código. También hemos explorado los casos de uso más apropiados y algunas buenas prácticas para utilizar esta estructura de manera efectiva.
Aunque tiene algunas limitaciones, como la restricción a comparaciones estrictas y la incapacidad de manejar rangos directamente, el switch
sigue siendo una estructura fundamental en JavaScript para ciertos tipos de lógica condicional, especialmente cuando tratamos con valores enumerados o categorías bien definidas.