Free

Estructuras de control

Activar audio

Domina las estructuras de control en JavaScript: condicionales, bucles, switch, ternarios y sus trampas. Aprende cuándo usar cada una y evita errores silenciosos.

Las estructuras de control permiten modificar el flujo de ejecución de un programa. En JavaScript, son fundamentales para tomar decisiones, repetir tareas y construir lógica condicional y repetitiva de forma precisa.

Condicionales

if / else

Permite ejecutar un bloque de código u otro según si una condición se evalúa como verdadera o falsa.

const age = 20;

if (age >= 18) {
  console.log("You can vote");
} else {
  console.log("Too young to vote");
}

else if

Permite encadenar múltiples condiciones y ejecutar diferentes bloques según cuál se cumpla primero.

const score = 85;

if (score >= 90) {
  console.log("A grade");
} else if (score >= 80) {
  console.log("B grade");
} else {
  console.log("Below B");
}

switch

Evalúa un mismo valor contra múltiples posibles casos. Útil para condiciones exactas.

const fruit = "apple";

switch (fruit) {
  case "banana":
    console.log("Yellow fruit");
    break;
  case "apple":
    console.log("Red or green fruit");
    break;
  default:
    console.log("Unknown fruit");
}

Bucles

while

Ejecuta un bloque de código mientras la condición se mantenga verdadera.

let i = 0;
while (i < 3) {
  console.log(i);
  i++;
}

do...while

Igual que while, pero garantiza que el bloque se ejecuta al menos una vez.

let i = 0;
do {
  console.log(i);
  i++;
} while (i < 3);

for

Bucle con contador. Se ejecuta mientras una condición sea verdadera, con control explícito del índice.

for (let i = 0; i < 3; i++) {
  console.log(i);
}

for...of

Itera sobre los valores de un iterable (array, string, Set, Map).

const colors = ["red", "green", "blue"];

for (const color of colors) {
  console.log(color);
}

for...in

Itera sobre las claves (propiedades enumerables) de un objeto.

const user = { name: "Ana", age: 30 };

for (const key in user) {
  console.log(`${key}: ${user[key]}`);
}

for...in vs for...of

Característica for...in for...of
Itera Claves (índices o propiedades) Valores
Sirve para Objetos planos, arrays con propiedades Arrays, strings, Sets, Maps
Incluye propiedades heredadas No
Ideal para Recorrer objetos Recorrer colecciones

Nota sobre arrays dispersos (sparse arrays)

const arr = [];
arr[3] = 'x';

Un array disperso tiene huecos (índices no definidos). for...in recorre los índices definidos, incluso si están vacíos. for...of ignora esos huecos.

for (const i in arr) {
  console.log(i); // 3
}

for (const value of arr) {
  console.log(value); // undefined x
}

Operador ternario

Forma corta de un if/else para asignaciones o evaluaciones simples.

const age = 18;
const result = (age >= 18) ? "Adult" : "Minor";

Evita ternarios anidados o difíciles de leer. Usa if/else si necesitas claridad o varias condiciones.

break y continue

break

Rompe completamente la ejecución de un bucle.

for (let i = 0; i < 5; i++) {
  if (i === 3) break;
  console.log(i);
}

continue

Salta a la siguiente iteración del bucle.

for (let i = 0; i < 5; i++) {
  if (i === 2) continue;
  console.log(i);
}

Cuándo usar cada uno

for...of vs forEach

  • Usa for...of si necesitas cortar la ejecución con break o continue.
  • Usa forEach para transformaciones simples donde no necesitas controlar el flujo.

switch vs if/else

  • switch: cuando comparas un mismo valor contra varios casos fijos.
  • if/else: cuando necesitas evaluar condiciones complejas o rangos.

Ternario vs if/else

  • Usa ternario para condiciones simples y asignaciones directas.
  • Evita ternarios con más de dos ramas o con lógica anidada.
  • Si necesitas claridad o varias condiciones, usa if/else.

Trampas comunes

  • Olvidar el break en un switch: provoca ejecuciones encadenadas.
  • Usar == en vez de ===: puede dar resultados inesperados (coercion).
  • Bucles infinitos por olvidar incrementar la variable de control.
  • Recorrer un array con for...in: puede incluir propiedades añadidas manualmente.
  • Modificar un array mientras lo recorres con for: puede romper los índices.

Enlaces útiles

Desafío Práctico: Estructuras de control JavaScript

Prueba a resolver este desafío antes de continuar

Trabajas en una startup de videojuegos y tu jefe necesita un sistema básico para analizar las puntuaciones de los jugadores. El juego acaba de lanzarse y están llegando miles de puntuaciones cada día.

El equipo de producto quiere entender cómo está funcionando el juego:

  • ¿Cuántos jugadores están en cada nivel de habilidad?.
  • ¿Qué tan rápido pueden encontrar jugadores "pro" para torneos?.
  • ¿Cuál es la puntuación máxima actual?.
  • ¿Cuántas partidas necesita un jugador promedio para llegar a cierto puntaje?.

Tu tarea es crear 5 funciones simples que respondan estas preguntas. Las puntuaciones van de 0 a 100 puntos.

// Example: array of player scores
const scores = [45, 78, 92, 23, 67, 88, 34, 56, 91];

// Your functions should do this:
countByLevel(scores);        // { high: 3, medium: 3, low: 3 }
findFirstAbove(scores, 80);  // 92 (first score >= 80)
getScoreLevel(78);          // "medium"
calculateStat(scores, "max"); // 92
addUntilTarget(scores, 200); // 3 (added 45+78+92 = 215)

Tu Código

Solución

Paso 1: Contar por Nivel (for...of + if/else if)

function countByLevel(scores) {
  const levels = { high: 0, medium: 0, low: 0 };

  for (const score of scores) {
    if (score >= 80) {
      levels.high++;
    } else if (score >= 50) {
      levels.medium++;
    } else {
      levels.low++;
    }
  }

  return levels;
}

Por qué if/else if: Cada puntuación va en exactamente una categoría.

Paso 2: Buscar Primera Puntuación Alta (for...of + return + continue)

function findFirstAbove(scores, target) {
  for (const score of scores) {
    // Skip invalid scores
    if (score < 0) continue;

    if (score >= target) {
      return score; // Found it - stop searching
    }
  }

  return -1; // Not found
}

Por qué continue: Saltamos puntuaciones inválidas sin anidar más ifs. Por qué return: Para el bucle inmediatamente cuando encontramos coincidencia.

Paso 3: Clasificar Puntuación Individual (if/else if)

function getScoreLevel(score) {
  if (score >= 80) {
    return "high";
  } else if (score >= 50) {
    return "medium";
  } else {
    return "low";
  }
}

Paso 4: Calcular Estadísticas (switch)

function calculateStat(scores, stat) {
  switch (stat) {
    case "max":
      let max = scores[0];
      for (const score of scores) {
        if (score > max) {
          max = score;
        }
      }
      return max;

    case "sum":
      let total = 0;
      for (const score of scores) {
        total += score;
      }
      return total;

    case "count":
      return scores.length;

    default:
      return 0;
  }
}

Por qué switch: 3 operaciones específicas, más claro que if/else if.

Paso 5: Sumar Hasta Objetivo (while)

function addUntilTarget(scores, target) {
  let total = 0;
  let count = 0;
  let index = 0;

  while (index < scores.length && total < target) {
    total += scores[index];
    count++;
    index++;
  }

  return count;
}

Por qué while: No sabemos cuántas puntuaciones necesitamos sumar para alcanzar el objetivo.

Solución Completa

const gameScores = [45, 78, 92, 23, 67, 88, 34, 56, 91];

function countByLevel(scores) {
  const levels = { high: 0, medium: 0, low: 0 };

  for (const score of scores) {
    if (score >= 80) {
      levels.high++;
    } else if (score >= 50) {
      levels.medium++;
    } else {
      levels.low++;
    }
  }

  return levels;
}

function findFirstAbove(scores, target) {
  for (const score of scores) {
    if (score < 0) continue;

    if (score >= target) {
      return score;
    }
  }

  return -1;
}

function getScoreLevel(score) {
  if (score >= 80) {
    return "high";
  } else if (score >= 50) {
    return "medium";
  } else {
    return "low";
  }
}

function calculateStat(scores, stat) {
  switch (stat) {
    case "max":
      let max = scores[0];
      for (const score of scores) {
        if (score > max) {
          max = score;
        }
      }
      return max;

    case "sum":
      let total = 0;
      for (const score of scores) {
        total += score;
      }
      return total;

    case "count":
      return scores.length;

    default:
      return 0;
  }
}

function addUntilTarget(scores, target) {
  let total = 0;
  let count = 0;
  let index = 0;

  while (index < scores.length && total < target) {
    total += scores[index];
    count++;
    index++;
  }

  return count;
}
Juan Andrés Núñez

Juan Andrés Núñez

Ingeniero Frontend Senior. Especialista en Vue.js. Speaker. Docente profesional. Estoico.