⚡ Curso JavaScript · Nivel N1 Principiante

Bloque 2: Control de flujo

Hasta ahora tus programas eran rectas: de arriba abajo, una vez. Hoy se convierten en auténticas máquinas: decidirán caminos con condicionales, combinarán condiciones con lógica booleana y repetirán trabajo miles de veces con bucles. Este bloque separa a quien «sigue tutoriales» de quien realmente piensa como programador.

⏱ ≈ 12 horas 📚 4 lecciones ✍️ 18 ejercicios de lógica 📝 Examen final superable (≥ 70 %)
Lección 1 · Teoría

Booleanos y operadores lógicos

Todo control de flujo descansa sobre un tipo humilde: el boolean, que solo puede valer true o false. Las comparaciones que conoces del bloque anterior son fábricas de booleanos:

comparaciones → booleanos
const edad = 17;

edad >= 18      // false
edad < 65       // true
edad !== 18     // true
typeof edad === "number"  // true ✔️

1.1 · Truthy y falsy: qué cuenta como «no»

Cuando JavaScript necesita un boolean y recibe otro valor, aplica esta regla. Solo seis valores son falsy; absolutamente todo lo demás es truthy:

Los seis valores falsy (apréndelos de memoria)
ValorEs…Sorpresa habitual
falseel boolean falso—
0 y -0cero numérico"0" NO es falsy: es texto truthy 😅
""cadena vacía" " (con espacio) es truthy
nullvacío intencionado—
undefinedvalor ausente—
NaNnúmero inválido—
💡 Compruébalo tú mismo/a: Boolean("") → false, Boolean("0") → true, Boolean(-5) → true. Esta conversión silenciosa decide qué rama se ejecuta.

1.2 · Operadores lógicos: && , || y !

Combinando condiciones
OperadorNombreDevuelve true si…
&&AND (y)TODAS las condiciones son verdaderas
||OR (o)AL MENOS UNA es verdadera
!NOT (no)invierte el valor: !true → false
combinaciones reales
const edad = 20;
const tieneCarnet = true;

edad >= 18 && tieneCarnet   // true: ambas se cumplen → puede conducir
edad < 12 || edad > 64      // false: ninguna se cumple
!tieneCarnet               // false: invierte el boolean
⚠️ Evaluación en cortocircuito: con &&, si la primera parte es falsy, JavaScript ya no mira la segunda. Con ||, si la primera es truthy, tampoco. Se aprovecha mucho: nombre || "Anónimo".
Lección 2 · Teoría

Condicionales: if / else if / else

La estructura que da voluntad propia a tus programas: «si se cumple esto, hazlo; si no, haz lo otro».

anatomía completa
const nota = 7;

if (nota >= 9) {
  console.log("Sobresaliente");
} else if (nota >= 5) {
  console.log("Aprobado");
} else {
  console.log("Suspenso");
}
  • Las ramas se evalúan en orden: en cuanto una condición es verdad, se entra en ella y las demás se ignoran.
  • else es el «resto de casos»: no lleva condición y siempre es opcional.
  • Ordena los rangos de mayor a menor (o al revés): si preguntas primero nota >= 5, un 9 entraría ahí y jamás llegaría al sobresaliente.
  • Las llaves { } son obligatorias en este curso, aunque solo haya una línea. Previenen bugs al ampliar código.

2.1 · El bug nº 1 del planeta JavaScript

❌ asignación accidental
if (edad = 18) {
  // ¡esto ASIGNA 18 a edad!
  // 18 es truthy → SIEMPRE entra aquí
}
✅ comparación real
if (edad === 18) {
  // compara: solo entra si vale exactamente 18
}
⚠️ Un solo = dentro de un if es asignación, no comparación. El laboratorio de este bloque te lo va a exigir corregido.

2.2 · El ternario: if compacto de una línea

Para decisiones simples con dos valores, existe el operador condición ? sí : no:

versión larga
let entrada;
if (edad < 12) {
  entrada = 5;
} else {
  entrada = 9;
}
✅ versión ternario
const entrada = edad < 12 ? 5 : 9;
💡 Regla práctica: usa ternario cuando cabe en una línea y se lee de un vistazo. Si necesitas varias ramas o efectos secundarios, vuelve al if/else.
Lección 3 · Teoría

switch: múltiples caminos

Cuando comparas la misma variable contra muchos valores exactos, switch es más limpio que una escalera de else if:

anatomía del switch
const dia = "sabado";

switch (dia) {
  case "lunes":
    console.log("Inicio de semana");
    break;                // ← imprescindible: cierra el caso

  case "sabado":           // ← casos agrupados comparten código
  case "domingo":
    console.log("¡Fin de semana!");
    break;

  default:                 // ← el "else" del switch
    console.log("Entre semana");
}
⚠️ Si olvidas un break, la ejecución «se cae» al caso siguiente (fall-through). A veces se aprovecha para agrupar casos como arriba, pero por accidente es una fuente clásica de bugs.
¿switch o else if?
Usa switch cuando…Usa else if cuando…
Comparas UNA variable contra valores EXACTOS (días, menús, comandos) Las condiciones son rangos (>= 9) o combinaciones (&&, ||)
Hay 3 o más valores posibles Solo hay 2 ramas (ahí brilla el if/else o el ternario)
💡 switch compara con igualdad estricta interna (===): case "2" NO atrapa el número 2.
Lección 4 · Teoría

Bucles: for, while, break y continue

Los ordenadores no se cansan: repiten operaciones millones de veces sin quejarse. El bucle for clásico tiene tres partes separadas por punto y coma:

tabla del 7 en diez líneas
for (let i = 1; i <= 10; i++) {
  console.log(`7 x ${i} = ${7 * i}`);
}
// ① let i = 1  → arranque (se ejecuta UNA vez)
// ② i <= 10    → ¿seguimos? (se comprueba en cada vuelta)
// ③ i++        → paso (al final de cada vuelta)

4.1 · while y do…while

while: comprueba ANTES
let combustible = 3;

while (combustible > 0) {
  console.log(`Ronda con ${combustible}`);
  combustible--;
}
do…while: ejecuta AL MENOS una vez
let pin = "";

do {
  // pedir PIN al menos una vez
  pin = "1234";
} while (pin !== "1234");
⚠️ Bucle infinito: si la condición nunca pasa a ser falsy (olvidas i++ o restar combustible), el navegador se congela. Ante una pestaña colgada: cerrar pestaña y revisar el paso del bucle.

4.2 · break y continue: freno y atajo

dos mandos de control
for (let vuelta = 1; vuelta <= 10; vuelta++) {
  if (vuelta % 2 !== 0) {
    continue;  // impar → saltamos a la SIGUIENTE vuelta
  }

  console.log(`Vuelta par: ${vuelta}`);

  if (vuelta === 6) {
    break;     // salimos del bucle DEFINITIVAMENTE
  }
}
// Imprime: 2, 4, 6 — y ahí se acaba

4.3 · El patrón acumulador

Quizá el patrón más usado de la programación: una variable arranca en cero y el bucle le va sumando resultados:

suma del 1 al 100
let suma = 0;              // el acumulador

for (let n = 1; n <= 100; n++) {
  suma += n;               // cada vuelta deja su grano de arena
}

console.log(suma);         // 5050 — Gauss tenía razón
💡 Combina todo lo aprendido: un bucle cuyo cuerpo contiene if / else if / else con condiciones compuestas es el corazón de la mayoría de programas reales. El ejercicio 18 (FizzBuzz integrador) es exactamente eso.
Práctica guiada

✍️ Los 18 ejercicios del bloque

Crea la carpeta js-b2/ y resuelve en orden — cada ejercicio encadena el anterior. Trabaja en archivos ej01.html, ej02.html… con un <script> al final del body y abre la consola (F12). Recuerda: comparaciones con ===, llaves siempre, y cero alert().

Sección A · Condicionales

1 El semáforo

const luz = "roja";. Con un if/else imprime «STOP» si es roja y «AVANZA» en cualquier otro caso. Prueba cambiando el valor.

Ver solución
const luz = "roja";

if (luz === "roja") {
  console.log("STOP");
} else {
  console.log("AVANZA");
}

2 Portero de discoteca

let edad = 16;. Imprime «Bienvenida/o» si es mayor o igual de 18 y «Lo siento, menores fuera» si no.

Ver solución
let edad = 16;

if (edad >= 18) {
  console.log("Bienvenida/o");
} else {
  console.log("Lo siento, menores fuera");
}

3 Corrector de notas

Con let nota = 8.4; construye la escalera else if completa: sobresaliente (>= 9), notable (>= 7), aprobado (>= 5) y suspenso (resto). Prueba con 9.1, 7, 5 y 2.

Ver solución
let nota = 8.4;

if (nota >= 9) {
  console.log("Sobresaliente");
} else if (nota >= 7) {
  console.log("Notable");
} else if (nota >= 5) {
  console.log("Aprobado");
} else {
  console.log("Suspenso");
}

4 Entrada en una línea

Reescribe el precio del cine con un único ternario: menores de 12 pagan 5 €, el resto 9 €. Muestra la frase completa con template literal.

Ver solución
const edad = 10;
const precio = edad < 12 ? 5 : 9;

console.log(`Entrada: ${precio} €`);

5 Caza del bug

Este fragmento «funciona» pero está mal: if (acceso = true) { ... }. Explica en un comentario por qué SIEMPRE se cumple, corrígelo con === y demuéstralo probando con false.

Ver solución
const acceso = false;

// BUG: "=" asignaba true a acceso y true es truthy:
// la condición valía SIEMPRE, aunque acceso fuese false.
if (acceso === true) {
  console.log("Puerta abierta");
} else {
  console.log("Puerta cerrada"); // ✔️ ahora sí sale esto
}

Sección B · Lógica booleana

6 Descuento doble

Hay descuento si el cliente es menor de 12 O mayor de 64, Y además no es festivo. Declara las tres variables y muestra con un if/else si paga menos.

Ver solución
const edad = 70;
const esFestivo = false;

if ((edad < 12 || edad > 64) && !esFestivo) {
  console.log("Descuento aplicado");
} else {
  console.log("Precio normal");
}

7 Detector truthy/falsy

Predice en un comentario qué devolverá Boolean() para: 0, -3, "", " ", "0", null y undefined. Después compruébalo imprimiendo cada uno.

Ver solución
// Predicciones: false, true, false, TRUE, TRUE, false, false
console.log(Boolean(0));         // false ✔️
console.log(Boolean(-3));        // true ✔️
console.log(Boolean(""));        // false ✔️
console.log(Boolean(" "));       // true: ¡contiene un espacio!
console.log(Boolean("0"));       // true: es TEXTO, no cero
console.log(Boolean(null));      // false ✔️
console.log(Boolean(undefined)); // false ✔️

8 Login de juguete

usuario = "ada", clave = "1234". Muestra «Acceso concedido» solo si AMBOS coinciden con los esperados usando && y ===. Prueba a fallar uno de los dos.

Ver solución
const usuario = "ada";
const clave = "1234";

if (usuario === "ada" && clave === "1234") {
  console.log("Acceso concedido");
} else {
  console.log("Credenciales incorrectas");
}

9 Día libre

esViernes = true y hayReunion = false. Con una sola condición usando ! y &&, imprime «Día libre» si NO hay reunión y ES viernes. Prueba las cuatro combinaciones.

Ver solución
const esViernes = true;
const hayReunion = false;

if (esViernes && !hayReunion) {
  console.log("Día libre");
} else {
  console.log("A trabajar");
}

Sección C · switch

10 Barra de café

const pedido = "latte";. Con switch: espresso → 1,20 €, latte → 1,80 €, capuchino → 2,10 €, y default para «No tenemos ese pedido». Incluye todos los break.

Ver solución
const pedido = "latte";

switch (pedido) {
  case "espresso":
    console.log("Son 1,20 €");
    break;
  case "latte":
    console.log("Son 1,80 €");
    break;
  case "capuchino":
    console.log("Son 2,10 €");
    break;
  default:
    console.log("No tenemos ese pedido");
}

11 Casos agrupados

Añade al ejercicio 10 los pedidos «tostada» y «croissant» agrupándolos en un mismo caso («Son 1,50 €») usando el fall-through a propósito.

Ver solución
switch (pedido) {
  // ...casos anteriores...
  case "tostada":      // sin break: cae al caso siguiente
  case "croissant":
    console.log("Son 1,50 €");
    break;
  // ...default...
}

12 Traducción switch → else if

Rewrite del ejercicio 10 con la escalera else if. ¿Cuál versión se lee mejor? Deja tu veredicto en un comentario final.

Ver solución
if (pedido === "espresso") {
  console.log("Son 1,20 €");
} else if (pedido === "latte") {
  console.log("Son 1,80 €");
} else if (pedido === "capuchino") {
  console.log("Son 2,10 €");
} else if (pedido === "tostada" || pedido === "croissant") {
  console.log("Son 1,50 €");
} else {
  console.log("No tenemos ese pedido");
}
// Veredicto sugerido: con tantos valores exactos, switch gana en claridad.

Sección D · Bucles

13 Tabla del 7

Con un bucle for imprime las diez líneas de la tabla del 7 en formato 7 x 3 = 21, usando template literal.

Ver solución
for (let i = 1; i <= 10; i++) {
  console.log(`7 x ${i} = ${7 * i}`);
}

14 Cuenta atrás y despegue

Con un while, cuenta atrás desde 10 hasta 1 e imprime «🚀 Despegue» al salir del bucle. Ojo: no olvides decrementar o la consola se congela.

Ver solución
let contador = 10;

while (contador > 0) {
  console.log(contador);
  contador--;          // sin esto: bucle infinito 💥
}

console.log("🚀 Despegue");

15 Solo pares

Recorre del 1 al 20 con for y usa continue para saltarte los impares. Solo deben imprimirse 2, 4, 6… 20.

Ver solución
for (let n = 1; n <= 20; n++) {
  if (n % 2 !== 0) {
    continue;   // impar → siguiente vuelta
  }
  console.log(n);
}

16 Acumulador de gastos

Simula cinco compras de importes fijos (23.50, 8, 41.20, 15, 6.75) sumándolas en un acumulador dentro de un bucle. Muestra el total final formateado con `Total: ${total} €`. Pista: declara let total = 0; antes.

Ver solución
let total = 0;

for (let compra = 1; compra <= 5; compra++) {
  // importe fijo por compra (en un bloque posterior será un array)
  if (compra === 1) total += 23.50;
  if (compra === 2) total += 8;
  if (compra === 3) total += 41.20;
  if (compra === 4) total += 15;
  if (compra === 5) total += 6.75;
}

console.log(`Total: ${total} €`); // Total: 94.45 €

17 FizzBuzz

El ejercicio de entrevista más famoso del mundo: del 1 al 30, imprime «Fizz» en los múltiplos de 3, «Buzz» en los de 5 y «FizzBuzz» en los de ambos. El resto, el número. Pista: pregunta PRIMERO por el 15.

Ver solución
for (let n = 1; n <= 30; n++) {
  if (n % 15 === 0) {
    console.log("FizzBuzz");   // divisible entre 3 Y 5: PRIMERO
  } else if (n % 3 === 0) {
    console.log("Fizz");
  } else if (n % 5 === 0) {
    console.log("Buzz");
  } else {
    console.log(n);
  }
}

18 🏆 Proyecto integrador: «maquina-decisiones.html»

Une TODO el bloque en una sola página que simule el turno de una guardia médica:

  • Al menos dos estructuras if con ramas else/else if
  • Todas las igualdades con ===/!== (prohibido ==/!=) y alguna condición combinada con && u ||
  • Un bucle for o while con contador o acumulador (++, --, +=, -=…)
  • break o continue controlando el bucle
  • Ninguna asignación = dentro de las condiciones de if/while (el bug del ejercicio 5)

Idea guía: pacientes que llegan con niveles de urgencia 1-5; atiende mientras haya turnos, salta los de urgencia baja con continue y detiene la sala con break al llegar a una emergencia.

Este ejercicio es el reto del laboratorio del examen: la validación automática comprobará estos criterios por ti.

Evaluación del bloque

📝 Examen del Bloque 2

Dos partes: un test teórico autoevaluable (mínimo 70 %) y un reto práctico de autocorrección con checklist.

Parte A · Test teórico (aprueba con 10/14)

1 · ¿Qué devuelve typeof true?
2 · ¿Cuál de estos valores es falsy?
3 · ¿Qué imprime console.log(2 > 3)?
4 · ¿Qué operador exige que TODAS las condiciones se cumplan?
5 · ¿Cuándo se ejecuta el bloque else?
6 · ¿Qué hace realmente if (edad = 18) { … }?
7 · ¿Qué operador compara VALOR y TIPO a la vez?
8 · En un switch, ¿qué ocurre si olvidas un break?
9 · ¿Cuántas veces imprime for (let i = 0; i < 3; i++)?
10 · ¿Qué garantiza un bucle do…while frente a un while?
11 · ¿Qué hace exactamente continue?
12 · En FizzBuzz, ¿por qué se pregunta n % 15 === 0 primero?
13 · ¿Qué sentencia ABANDONA el bucle inmediatamente?
14 · El patrón let total = 0; … total += n; dentro de un bucle se llama…

Parte B · Reto práctico final

Construye el ejercicio 18 («maquina-decisiones.html») sin mirar soluciones y valida tú mismo/a estos criterios. Mínimo para aprobar: 7 de 8 casillas.

Cumplidos: 0 / 8

🎉 ¿Superaste las dos partes? Enhorabuena: has aprobado el Bloque 2 de JavaScript. Tus programas ya deciden y repiten como máquinas. En el Bloque 3 aprenderás a empaquetar esa lógica en piezas reutilizables: las funciones.