Al final de la lección anterior apareció una incomodidad concreta: dentro del bucle que recorría el backlog había que repetir una y otra vez la misma cadena de else if para convertir prioridad en un peso numérico. Ese patrón —una sola variable comparada contra una lista de valores fijos— es tan frecuente que JavaScript tiene una construcción dedicada: el switch. En esta lección aprenderás su sintaxis, entenderás por qué compara con === y qué consecuencias tiene, distinguirás el fall-through deliberado del accidental, verás por qué a veces un case necesita llaves y conocerás las dos alternativas con las que compite: la cadena else if de siempre y el objeto de consulta, que será tu herramienta preferida a partir del Módulo 4.

Contenido

  1. Cuándo un switch mejora una cadena de else if
  2. Sintaxis del switch
  3. Cómo compara: la igualdad estricta
  4. default: el caso por defecto
  5. break y el fall-through accidental
  6. Fall-through deliberado: agrupar casos
  7. Ámbito de las variables dentro de un case
  8. El patrón switch (true) y por qué evitarlo
  9. switch vs if/else if vs objeto de consulta
  10. Caso práctico: etiqueta visible del estado
  11. Caso práctico: prioridad a color y a peso
  12. Errores Comunes y Consejos
  13. Ejercicios
  14. Conclusión

  1. Cuándo un switch mejora una cadena de else if

Recupera el fragmento que se repetía en la lección 02-02:

let peso;
if (prioridades[i] === 'alta') {
  peso = 3;
} else if (prioridades[i] === 'media') {
  peso = 2;
} else if (prioridades[i] === 'baja') {
  peso = 1;
} else {
  peso = 0;
}

Hay algo mecánico en ese código: la parte izquierda de la comparación es siempre la misma y el operador también. Lo único que cambia es el valor de la derecha. Esa repetición es lo que el switch elimina: se escribe la expresión una vez y a continuación solo la lista de valores.

Un switch es la herramienta adecuada cuando se cumplen estas tres condiciones:

  • Se compara una sola expresión.
  • Se compara por igualdad exacta contra valores concretos, no por rangos ni por condiciones compuestas.
  • Hay tres o más casos. Con dos, un if/else es más corto y más claro.

Si alguna falla, la respuesta correcta sigue siendo un if/else if.

  1. Sintaxis del switch

const prioridad = 'media';
let peso;

switch (prioridad) {
  case 'alta':
    peso = 3;
    break;
  case 'media':
    peso = 2;
    break;
  case 'baja':
    peso = 1;
    break;
  default:
    peso = 0;
    console.error(`Prioridad desconocida: "${prioridad}"`);
}

console.log(`Peso: ${peso}`);   // Peso: 2

Las piezas:

Elemento Función
switch (expresión) Evalúa la expresión una sola vez y guarda su valor
case valor: Etiqueta un punto de entrada; si coincide, la ejecución salta aquí
break Sale del switch y continúa después de la llave de cierre
default: Punto de entrada cuando ningún case ha coincidido

Y el detalle que lo explica todo: case no es una condición, es una etiqueta de salto. El switch no evalúa caso por caso como un if/else if; busca el punto donde entrar y, a partir de ahí, ejecuta hacia abajo hasta encontrar un break o llegar al final del bloque. Entender esto hace que todo el resto de la lección resulte evidente.

flowchart TD
    A["switch (prioridad)"] --> B{"¿=== 'alta'?"}
    B -->|sí| C["peso = 3"] --> Z["break → salir"]
    B -->|no| D{"¿=== 'media'?"}
    D -->|sí| E["peso = 2"] --> Z
    D -->|no| F{"¿=== 'baja'?"}
    F -->|sí| G["peso = 1"] --> Z
    F -->|no| H["default: peso = 0"] --> Z
    Z --> I["Continúa el programa"]

Nota sobre el estilo: el bloque entero va entre llaves y los case no llevan llaves propias por defecto. La indentación habitual coloca los case un nivel dentro del switch y su cuerpo un nivel más adentro.

  1. Cómo compara: la igualdad estricta

El switch compara el valor de la expresión con cada case usando ===, la igualdad estricta que estableciste como norma en Conversión de Tipos y Comparaciones. No hay conversión de tipos de ningún tipo.

La consecuencia práctica es importante cuando los datos llegan de un formulario, donde todo es texto:

const horasDelFormulario = '12';   // ← string, viene de un <input>

switch (horasDelFormulario) {
  case 12:
    console.log('Doce horas');
    break;
  default:
    console.log('No coincide con ningún caso');   // ← se ejecuta esta
}

'12' === 12 es false, así que entra por default. La solución es la misma que ya conoces: convertir explícitamente antes de comparar.

switch (Number(horasDelFormulario)) {
  case 12:
    console.log('Doce horas');   // ✓ ahora sí
    break;
}

Que use === es una buena noticia: elimina las sorpresas de la conversión implícita. Pero hereda también su única rareza:

const valor = NaN;

switch (valor) {
  case NaN:
    console.log('Nunca llega aquí');
    break;
  default:
    console.log('NaN no es igual ni a sí mismo');   // ← se ejecuta esta
}

NaN === NaN es false, así que case NaN es inalcanzable. Para detectar un NaN sigue haciendo falta Number.isNaN() dentro de un if.

Y por la misma razón, un switch sobre objetos o arrays compara referencias, no contenidos, lo cual casi nunca es lo que quieres. En la práctica, el switch es una herramienta para valores primitivos: cadenas y números.

  1. default: el caso por defecto

default se ejecuta cuando ningún case coincide. Es el equivalente al else final de una cadena, y aplica la misma norma de la lección 02-01: inclúyelo siempre, aunque solo sea para registrar que ha llegado un valor inesperado.

default:
  peso = 0;
  console.error(`Prioridad desconocida: "${prioridad}"`);

Dos particularidades:

No tiene por qué ir al final. Es legal ponerlo en medio, y entonces sí necesita break para no continuar hacia los case siguientes. Es legal, pero desconcertante para quien lee: ponlo siempre al final.

El último bloque puede omitir el break. Si default es lo último, no hay nada debajo a lo que caer. Aun así, muchos equipos exigen escribirlo igualmente: el día que alguien añada un case detrás, el break ya estará ahí. Es una costumbre barata que evita un error caro.

  1. break y el fall-through accidental

Como el switch ejecuta hacia abajo desde el punto de entrada, olvidar un break hace que la ejecución se derrame al caso siguiente. A eso se le llama fall-through.

// ✗ Falta el break en 'alta'
const prioridad = 'alta';
let peso;

switch (prioridad) {
  case 'alta':
    peso = 3;
  case 'media':
    peso = 2;
    break;
  case 'baja':
    peso = 1;
    break;
}

console.log(peso);   // 2 ← ¡no 3!

La traza: entra por case 'alta', asigna peso = 3, no encuentra break, sigue hacia abajo, entra en el cuerpo de 'media' sin comprobar nada, asigna peso = 2 y ahí sí sale. El resultado es silenciosamente incorrecto.

Este error es especialmente traicionero porque no produce ningún aviso: JavaScript considera el fall-through una característica, no un fallo. La herramienta que sí te avisa es un linter como ESLint, con su regla no-fallthrough, que verás en Calidad de Código.

Mientras tanto, la protección es una costumbre: escribe el break inmediatamente después de abrir el case, antes de rellenar el cuerpo.

  1. Fall-through deliberado: agrupar casos

El mismo mecanismo, usado a propósito, es la mejor característica del switch: varios case seguidos, sin cuerpo entre ellos, comparten el mismo bloque.

En Nómada Tareas hay una pregunta que aparece constantemente: ¿esta tarea sigue abierta?

const estado = 'en-curso';
let sigueAbierta;

switch (estado) {
  case 'pendiente':
  case 'en-curso':
    sigueAbierta = true;
    break;
  case 'hecha':
    sigueAbierta = false;
    break;
  default:
    sigueAbierta = false;
    console.error(`Estado no reconocido: "${estado}"`);
}

console.log(sigueAbierta);   // true

case 'pendiente': no tiene cuerpo propio, así que la ejecución cae directamente al cuerpo de case 'en-curso':. Se lee de forma muy natural: "si es pendiente o en curso, entonces...".

Cuando el fall-through lleva código en el caso intermedio, la intención deja de ser evidente y hay que declararla con un comentario. Es la convención universal:

switch (nivelDeAviso) {
  case 'crítico':
    console.error('Avisar a Marta por teléfono');
    // fall through — un aviso crítico también manda correo
  case 'importante':
    console.warn('Enviar correo al responsable');
    break;
  case 'informativo':
    console.log('Solo aparece en el tablero');
    break;
}

Con 'crítico' se ejecutan las dos primeras acciones. Sin el comentario // fall through, cualquiera que revise el código lo tomaría por un break olvidado y lo "arreglaría", rompiendo la funcionalidad. Todo fall-through con código intermedio debe llevar ese comentario.

  1. Ámbito de las variables dentro de un case

Aquí hay una sutileza que sorprende a mucha gente: todos los case de un switch comparten un único ámbito de bloque, el del propio switch. No hay un ámbito por caso.

Eso provoca un error real:

// ✗ SyntaxError: Identifier 'etiqueta' has already been declared
switch (estado) {
  case 'pendiente':
    const etiqueta = 'Por empezar';
    console.log(etiqueta);
    break;
  case 'en-curso':
    const etiqueta = 'En marcha';   // ✗ el mismo nombre, el mismo ámbito
    console.log(etiqueta);
    break;
}

Y otro más sutil, que no falla al escribir sino al ejecutar:

// ✗ ReferenceError: Cannot access 'peso' before initialization
switch (prioridad) {
  case 'media':
    console.log(peso);          // la declaración de abajo existe, pero aún no está inicializada
    break;
  case 'alta':
    const peso = 3;
    break;
}

Es la zona muerta temporal de let y const que viste en Variables y Tipos de Datos, aplicada al bloque completo del switch.

La solución es dar a cada caso sus propias llaves:

switch (estado) {
  case 'pendiente': {
    const etiqueta = 'Por empezar';
    console.log(etiqueta);
    break;
  }
  case 'en-curso': {
    const etiqueta = 'En marcha';   // ✓ ámbito propio, sin conflicto
    console.log(etiqueta);
    break;
  }
}

Fíjate en dónde va el break: dentro de las llaves. Las llaves delimitan el ámbito, no el caso.

Norma práctica: si un case declara variables, ponle llaves. Si solo asigna a variables ya declaradas fuera —que es el uso más común—, no hacen falta.

  1. El patrón switch (true) y por qué evitarlo

switch compara por igualdad, así que en principio no sirve para rangos. Existe un truco para forzarlo: poner true como expresión y condiciones completas en cada case.

// △ Funciona, pero no lo escribas
const horasEstimadas = 12;
let carga;

switch (true) {
  case horasEstimadas <= 0 || horasEstimadas > 40:
    carga = 'inválida';
    break;
  case horasEstimadas <= 4:
    carga = 'ligera';
    break;
  case horasEstimadas <= 15:
    carga = 'media';
    break;
  default:
    carga = 'pesada';
}

console.log(carga);   // media

El mecanismo es coherente: la expresión vale true, cada case se evalúa y produce true o false, y se entra por el primero cuyo valor sea true.

Y, sin embargo, hay tres razones sólidas para no usarlo:

  1. Miente sobre lo que hace. Un lector espera que switch (x) compare valores de x; aquí switch (true) no compara nada útil y hay que leer todos los case para entender la lógica.
  2. Es exactamente un if/else if con peor sintaxis. Compara la versión equivalente: mismas condiciones, mismo orden, mismo resultado, cuatro caracteres menos de ruido por caso y ningún break que olvidar.
  3. Es frágil. Un break olvidado en esta versión no salta a otro caso equivalente, sino que ejecuta una asignación cuya condición era falsa.
// ✓ La versión correcta
if (horasEstimadas <= 0 || horasEstimadas > 40) {
  carga = 'inválida';
} else if (horasEstimadas <= 4) {
  carga = 'ligera';
} else if (horasEstimadas <= 15) {
  carga = 'media';
} else {
  carga = 'pesada';
}

La regla completa: switch para valores exactos, if/else if para rangos y condiciones compuestas. No hay excepciones que merezcan la pena.

  1. switch vs if/else if vs objeto de consulta

Hay una tercera forma de resolver estas conversiones, y es la que dominará el resto del curso: un objeto de consulta (lookup), una tabla que asocia cada valor de entrada con su resultado.

Los objetos se estudian a fondo en Introducción a los Objetos; aquí basta con la idea: se escriben entre llaves como pares clave: valor y se consultan con corchetes.

const PESOS = { alta: 3, media: 2, baja: 1 };

const prioridad = 'media';
const peso = PESOS[prioridad] ?? 0;

console.log(peso);   // 2

Cuatro líneas se convierten en dos, y el ?? que aprendiste en Operadores Básicos cubre el caso por defecto: si prioridad no está en la tabla, PESOS[prioridad] da undefined y ?? lo sustituye por 0.

La comparación completa:

Criterio if / else if switch Objeto de consulta
Comparar una variable con valores exactos △ Verboso ✓ Ideal ✓ Ideal
Rangos y condiciones compuestas ✓ La única opción ✗ Solo con el truco switch(true) ✗ No sirve
Ejecutar acciones distintas por caso ✓ Sí ✓ Sí △ Necesita funciones (Módulo 3)
Agrupar varios valores en un mismo caso △ Con || ✓ Fall-through deliberado △ Repetir la clave
Añadir un caso nuevo Editar código Editar código Añadir una línea de datos
Riesgo de olvidar algo Olvidar el else Olvidar el break Ninguno
Valor por defecto else default ??
Legibilidad con 10+ casos ✗ Mala △ Aceptable ✓ Excelente

La conclusión práctica que aplicarás a partir de ahora:

  • Mapear un valor a otro valor (estado → etiqueta, prioridad → color): objeto de consulta.
  • Ejecutar acciones distintas según un valor: switch.
  • Decidir por rangos o condiciones compuestas: if / else if.

Que el objeto de consulta gane en tantas casillas no convierte al switch en inútil: aparece constantemente en código real —especialmente en reductores de Redux, que verás en el Módulo 10— y tienes que saber leerlo y escribirlo con soltura.

  1. Caso práctico: etiqueta visible del estado

Los valores internos del proyecto ('pendiente', 'en-curso', 'hecha') están pensados para el código, no para Marta. La interfaz necesita textos presentables, y aquí el switch hace más que una simple traducción: elige también el icono y el nivel de aviso de la consola.

const estados = ['en-curso', 'pendiente', 'pendiente', 'hecha', 'en-curso', 'pendiente'];
const titulos = [
  'Rediseñar la sala polivalente',
  'Cartelería del taller de serigrafía',
  'Actualizar la web de reservas',
  'Inventario de tintas de serigrafía',
  'Guía de encuadernación para residentes',
  'Presupuesto de la carpintería'
];

for (let i = 0; i < estados.length; i++) {
  let etiqueta;
  let icono;

  switch (estados[i]) {
    case 'pendiente':
      etiqueta = 'Por empezar';
      icono = '○';
      break;
    case 'en-curso':
      etiqueta = 'En marcha';
      icono = '◐';
      break;
    case 'hecha':
      etiqueta = 'Completada';
      icono = '●';
      break;
    default:
      etiqueta = 'Estado desconocido';
      icono = '?';
      console.error(`Tarea ${i + 1}: estado no válido "${estados[i]}"`);
  }

  console.log(`${icono} ${titulos[i]} — ${etiqueta}`);
}

Salida:

◐ Rediseñar la sala polivalente — En marcha
○ Cartelería del taller de serigrafía — Por empezar
○ Actualizar la web de reservas — Por empezar
● Inventario de tintas de serigrafía — Completada
◐ Guía de encuadernación para residentes — En marcha
○ Presupuesto de la carpintería — Por empezar

Comprueba que se cumplen las tres condiciones de la sección 1: una sola expresión (estados[i]), igualdad exacta y tres casos. El switch está bien empleado. Y nota que let etiqueta; e let icono; se declaran dentro del bucle pero fuera del switch: dentro del bucle porque cambian en cada vuelta, fuera del switch porque hay que usarlas después de que termine.

  1. Caso práctico: prioridad a color y a peso

La regla R10 pide destacar visualmente las tareas. Cada prioridad tiene un color en la interfaz y un peso numérico para ordenar el tablero, y un mismo switch puede asignar las dos cosas a la vez en cada rama: es una ventaja frente al objeto de consulta, que necesitaría una tabla por campo.

const prioridades = ['alta', 'media', 'alta', 'baja', 'media', 'alta'];
const horas = [12, 6, 14, 3, 8, 5];

let esfuerzoTotal = 0;

for (let i = 0; i < prioridades.length; i++) {
  let color;
  let peso;

  switch (prioridades[i]) {
    case 'alta':
      color = '#c0392b';   // rojo
      peso = 3;
      break;
    case 'media':
      color = '#e67e22';   // naranja
      peso = 2;
      break;
    case 'baja':
      color = '#27ae60';   // verde
      peso = 1;
      break;
    default:
      color = '#7f8c8d';   // gris
      peso = 0;
      console.error(`Prioridad no válida: "${prioridades[i]}"`);
  }

  esfuerzoTotal += peso * horas[i];
  console.log(`${prioridades[i].padEnd(6)} ${color}  peso ${peso}  esfuerzo ${peso * horas[i]}`);
}

console.log(`Esfuerzo ponderado del backlog: ${esfuerzoTotal}`);

Salida:

alta   #c0392b  peso 3  esfuerzo 36
media  #e67e22  peso 2  esfuerzo 12
alta   #c0392b  peso 3  esfuerzo 42
baja   #27ae60  peso 1  esfuerzo 3
media  #e67e22  peso 2  esfuerzo 16
alta   #c0392b  peso 3  esfuerzo 15
Esfuerzo ponderado del backlog: 124

padEnd(6) rellena el texto con espacios hasta llegar a 6 caracteres, para que las columnas queden alineadas en la consola.

Ahora, la misma lógica con objetos de consulta, para que veas hacia dónde va el curso:

const COLORES = { alta: '#c0392b', media: '#e67e22', baja: '#27ae60' };
const PESOS   = { alta: 3, media: 2, baja: 1 };

for (let i = 0; i < prioridades.length; i++) {
  const color = COLORES[prioridades[i]] ?? '#7f8c8d';
  const peso  = PESOS[prioridades[i]] ?? 0;
  console.log(`${prioridades[i].padEnd(6)} ${color}  peso ${peso}`);
}

Veinte líneas se convierten en cuatro, y añadir una prioridad 'urgente' sería añadir un par en cada tabla en lugar de un case en cada switch. Cuando los datos de configuración se separan de la lógica que los usa, el código encoge. Esa idea recorre el resto del curso.

Errores Comunes y Consejos

Olvidar el break. El error número uno del switch. Se manifiesta como un valor final incorrecto, sin mensaje de error. Escríbelo siempre nada más abrir el case.

Confiar en la conversión de tipos. switch usa ===. Si la expresión puede venir como texto de un formulario, conviértela antes: switch (Number(campo)).

Poner condiciones en los case. case horas > 10: compara el valor de la expresión con el booleano resultante, que casi nunca es lo que quieres. Para rangos, if/else if.

Declarar const o let en varios case sin llaves. Provoca SyntaxError por redeclaración o ReferenceError por la zona muerta temporal. Pon llaves a los casos que declaren variables.

Omitir el default. Sin él, un valor inesperado deja las variables en undefined y el fallo emerge más tarde, en otro sitio. Inclúyelo siempre, aunque solo registre el error.

Usar switch con dos casos. if/else es más corto y más legible. El switch empieza a compensar a partir de tres.

Usar switch con objetos o arrays. Compara referencias, no contenido: dos arrays con los mismos elementos nunca coinciden. El switch es para primitivos.

Consejo: ordena los case por frecuencia o alfabéticamente. No afecta al rendimiento —el motor optimiza el salto—, pero facilita localizar un caso concreto y detectar si falta alguno.

Consejo: cuando un switch supere los diez casos o solo mapee valores, pásalo a objeto de consulta. Es la evolución natural, y con lo del Módulo 4 podrás hacerla sin esfuerzo.

Ejercicios

Ejercicio 1 — Días de margen por prioridad

Taller Nómada define un margen recomendado de aviso según la prioridad: 'alta' avisa con 3 días de antelación, 'media' con 7 y 'baja' con 14. Escribe un switch que, a partir de prioridad, asigne diasDeAviso, y usa un default que asigne 7 días y registre un error. Pruébalo con 'alta', 'baja' y 'urgentísima'.

Ejercicio 2 — Agrupar estados con fall-through

Escribe un switch sobre estado que asigne dos variables: enTablero (booleano: si la tarea debe seguir mostrándose en el tablero activo) y mensaje. Los estados 'pendiente' y 'en-curso' comparten el mismo tratamiento (enTablero = true), mientras que 'hecha' sale del tablero. Aprovecha el fall-through deliberado para no repetir código y recorre con un bucle el array ['en-curso', 'pendiente', 'hecha', 'archivada'] comprobando también el default.

Ejercicio 3 — Del switch al objeto de consulta

Este switch convierte el código de un taller en su nombre completo. Reescríbelo usando un objeto de consulta y ??, y explica en qué casos la versión con switch seguiría siendo preferible.

let nombreTaller;
switch (codigo) {
  case 'SER': nombreTaller = 'Serigrafía'; break;
  case 'ENC': nombreTaller = 'Encuadernación'; break;
  case 'CAR': nombreTaller = 'Carpintería'; break;
  case 'COW': nombreTaller = 'Coworking'; break;
  default:    nombreTaller = 'Sin clasificar';
}

Soluciones

Ejercicio 1

const prioridad = 'alta';
let diasDeAviso;

switch (prioridad) {
  case 'alta':
    diasDeAviso = 3;
    break;
  case 'media':
    diasDeAviso = 7;
    break;
  case 'baja':
    diasDeAviso = 14;
    break;
  default:
    diasDeAviso = 7;
    console.error(`Prioridad no reconocida: "${prioridad}". Se aplica el margen estándar.`);
}

console.log(`Avisar con ${diasDeAviso} día(s) de antelación.`);
// Avisar con 3 día(s) de antelación.

Con 'baja' da 14 días. Con 'urgentísima' entra en default, registra el error y aplica 7 días: el programa no se detiene y toma una decisión razonable, que es justo lo que debe hacer un default bien escrito. Un default que dejara diasDeAviso sin asignar propagaría un undefined hasta un cálculo posterior, donde el error aparecería sin ninguna pista de su origen.

Ejercicio 2

const estadosDePrueba = ['en-curso', 'pendiente', 'hecha', 'archivada'];

for (let i = 0; i < estadosDePrueba.length; i++) {
  const estado = estadosDePrueba[i];
  let enTablero;
  let mensaje;

  switch (estado) {
    case 'pendiente':
    case 'en-curso':
      enTablero = true;
      mensaje = 'Sigue en el tablero activo';
      break;
    case 'hecha':
      enTablero = false;
      mensaje = 'Movida al histórico';
      break;
    default:
      enTablero = false;
      mensaje = 'Estado no reconocido: se oculta por seguridad';
      console.error(`Estado inválido: "${estado}"`);
  }

  console.log(`${estado.padEnd(10)} → enTablero=${enTablero} · ${mensaje}`);
}

Salida:

en-curso   → enTablero=true · Sigue en el tablero activo
pendiente  → enTablero=true · Sigue en el tablero activo
hecha      → enTablero=false · Movida al histórico
archivada  → enTablero=false · Estado no reconocido: se oculta por seguridad

El fall-through deliberado está en case 'pendiente':, que no tiene cuerpo y cae al de 'en-curso'. Es el uso limpio de la característica: dos etiquetas, un solo bloque, cero duplicación. La alternativa con if sería if (estado === 'pendiente' || estado === 'en-curso'), igual de válida pero con la variable repetida.

Fíjate también en la decisión del default: ante un estado desconocido ocultamos la tarea en lugar de mostrarla. Es la política conservadora que ya aplicaste en la validación de transiciones de la lección 02-01: ante la duda, rechazar.

Ejercicio 3

const TALLERES = {
  SER: 'Serigrafía',
  ENC: 'Encuadernación',
  CAR: 'Carpintería',
  COW: 'Coworking'
};

const codigo = 'ENC';
const nombreTaller = TALLERES[codigo] ?? 'Sin clasificar';

console.log(nombreTaller);   // Encuadernación

Once líneas se convierten en tres más la tabla, y añadir un taller nuevo es añadir una línea de datos, no una rama de código. La tabla TALLERES además puede reutilizarse: para pintar un desplegable en el formulario o para validar que un código existe (TALLERES[codigo] === undefined).

Cuándo seguiría siendo preferible el switch:

  • Cuando cada caso ejecuta acciones distintas y no solo devuelve un valor: abrir una ventana, registrar un aviso, actualizar tres variables a la vez. Un objeto puede guardar funciones para eso, pero es una técnica del Módulo 3 en adelante.
  • Cuando algunos casos deben compartir bloque mediante fall-through, como el ejercicio 2.
  • Cuando las claves no son cadenas ni números simples, aunque en la práctica esto es raro.

En resumen: el objeto de consulta gana cuando la respuesta es un dato; el switch gana cuando la respuesta es un comportamiento.

Conclusión

Ya conoces la tercera estructura de selección de JavaScript. Sabes que un switch evalúa su expresión una vez, la compara con cada case mediante === sin conversión alguna, y que los case no son condiciones sino etiquetas de salto: la ejecución entra por la que coincide y baja hasta el primer break. De esa mecánica se derivan las dos caras del fall-through —el accidental, que asigna valores equivocados en silencio, y el deliberado, que agrupa varios valores en un mismo bloque y hay que documentar con un comentario— y también la necesidad de poner llaves a los case que declaran variables, porque todo el switch comparte un único ámbito.

Sabes cuándo usarlo: una sola expresión, valores exactos, tres o más casos. Y cuándo no: para rangos, if/else if, porque el truco switch (true) solo disfraza un if de otra cosa. Has visto además la tercera vía —el objeto de consulta con ?? para el caso por defecto—, que reduce a dos líneas cualquier conversión de valor a valor y que será tu opción por defecto en cuanto domines los objetos.

Aplicado al proyecto, ya traduces los estados internos a etiquetas presentables para Marta y conviertes la prioridad en color y en peso para ordenar el tablero.

Queda pendiente la incomodidad que arrastras desde la lección anterior: los bucles siguen recorriendo las seis tareas enteras aunque la respuesta ya se conozca en la primera, y todavía no sabes cruzar dos listas —los tres responsables contra las seis tareas— sin escribir contadores a mano. Ambas cosas se resuelven en Control del Flujo: break, continue y Bucles Anidados, donde aprenderás a interrumpir un bucle en el momento exacto, a saltarte las iteraciones que no interesan y a construir la matriz completa del tablero de Taller Nómada.

Curso de JavaScript: De Principiante a Avanzado

Módulo 1: Introducción a JavaScript

Módulo 2: Estructuras de Control

Módulo 3: Funciones

Módulo 4: Objetos y Arrays

Módulo 5: Objetos y Funciones Avanzadas

Módulo 6: El Modelo de Objetos del Documento (DOM)

Módulo 7: APIs del Navegador y Temas Avanzados

Módulo 8: Pruebas y Depuración

Módulo 9: Rendimiento y Optimización

Módulo 10: Frameworks y Librerías de JavaScript

Módulo 11: Proyecto Final

© Copyright 2026. Todos los derechos reservados