HDP115

Estructuras de Control

Aprende a controlar el flujo de ejecución en JavaScript mediante condicionales, bucles y manejo de errores.

CE

Cristian Escalante

Última actualización: 19 de abril de 2025

javascript
programación web
desarrollo frontend

Introducción a las estructuras de control

Las estructuras de control permiten alterar el flujo de ejecución de un programa, permitiendo tomar decisiones, repetir bloques de código y manejar errores. Son fundamentales para crear programas dinámicos que respondan a diferentes condiciones.

Declaraciones condicionales

if, else, else if

La estructura if permite ejecutar un bloque de código solo si una condición especificada es verdadera.

let edad = 18;

if (edad >= 18) {
  console.log("Eres mayor de edad");
}

Podemos añadir una alternativa con else:

let edad = 16;

if (edad >= 18) {
  console.log("Eres mayor de edad");
} else {
  console.log("Eres menor de edad");
}

Para múltiples condiciones, usamos else if:

let edad = 65;

if (edad < 13) {
  console.log("Eres un niño");
} else if (edad < 18) {
  console.log("Eres un adolescente");
} else if (edad < 65) {
  console.log("Eres un adulto");
} else {
  console.log("Eres un adulto mayor");
}

Consejos para usar condicionales

  • Las condiciones deben evaluar a un valor booleano (true o false)
  • JavaScript realiza coerción de tipos en las condiciones
  • Usa llaves {} incluso para bloques de una sola línea (mejora la legibilidad)
  • Evita anidar demasiados if (dificulta la lectura)

Operador condicional (ternario)

El operador ternario es una forma abreviada de escribir una instrucción if...else:

// Sintaxis: condición ? expresión_si_verdadero : expresión_si_falso

let edad = 20;
let mensaje = edad >= 18 ? "Mayor de edad" : "Menor de edad";
console.log(mensaje);  // "Mayor de edad"

Cuándo usar el operador ternario

  • Para asignaciones condicionales simples
  • Cuando necesitas una expresión condicional (no una declaración)
  • Para código compacto en casos sencillos

Cuándo evitar el operador ternario

  • En condiciones complejas
  • Cuando se anidan múltiples operadores ternarios
  • Cuando reduce la legibilidad del código

Estructura switch

La declaración switch evalúa una expresión y ejecuta el bloque de código correspondiente al valor que coincida:

let 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 inválido";
}

console.log(nombreDia);  // "Miércoles"

Características importantes de switch

  • La comparación se realiza con el operador de igualdad estricta (===)
  • La declaración break es necesaria para salir del switch después de ejecutar un caso
  • Si se omite break, la ejecución continuará con el siguiente caso ("fall-through")
  • El caso default se ejecuta cuando ningún caso coincide

Casos múltiples con el mismo código

let diaSemana = 6;
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 inválido";
}

console.log(tipoDeJornada);  // "Fin de semana"

Bucles

Los bucles permiten ejecutar un bloque de código repetidamente mientras se cumpla una condición.

Bucle while

El bucle while ejecuta un bloque de código mientras una condición sea verdadera:

let contador = 1;

while (contador <= 5) {
  console.log(`Iteración ${contador}`);
  contador++;
}
// Salida:
// Iteración 1
// Iteración 2
// Iteración 3
// Iteración 4
// Iteración 5

Bucle do-while

Similar a while, pero garantiza que el bloque de código se ejecute al menos una vez, ya que la condición se evalúa después de cada iteración:

let contador = 1;

do {
  console.log(`Iteración ${contador}`);
  contador++;
} while (contador <= 5);

La diferencia clave con while es que do-while siempre ejecuta el bloque al menos una vez:

let contador = 10;

// Este bloque no se ejecutará
while (contador <= 5) {
  console.log(`Iteración ${contador}`);
  contador++;
}

// Este bloque se ejecutará una vez
do {
  console.log(`Iteración ${contador}`);  // "Iteración 10"
  contador++;
} while (contador <= 5);

Bucle for

El bucle for es ideal cuando se conoce de antemano el número de iteraciones:

for (let i = 1; i <= 5; i++) {
  console.log(`Iteración ${i}`);
}

El bucle for consta de tres partes:

  1. Inicialización: let i = 1 (se ejecuta una vez al principio)
  2. Condición: i <= 5 (se evalúa antes de cada iteración)
  3. Expresión final: i++ (se ejecuta después de cada iteración)

Bucle for...in

El bucle for...in itera sobre las propiedades enumerables de un objeto:

const persona = {
  nombre: "Ana",
  edad: 28,
  profesion: "Ingeniera"
};

for (let propiedad in persona) {
  console.log(`${propiedad}: ${persona[propiedad]}`);
}
// Salida:
// nombre: Ana
// edad: 28
// profesion: Ingeniera

Nota importante: No se recomienda usar for...in para iterar sobre arrays, ya que también enumera propiedades heredadas y puede no seguir el orden numérico de los índices.

Bucle for...of

Introducido en ES6, for...of itera sobre elementos de objetos iterables (arrays, strings, maps, sets, etc.):

const colores = ["rojo", "verde", "azul"];

for (let color of colores) {
  console.log(color);
}
// Salida:
// rojo
// verde
// azul

Con strings:

const texto = "Hola";

for (let caracter of texto) {
  console.log(caracter);
}
// Salida:
// H
// o
// l
// a

Declaraciones break y continue

break

La declaración break termina el bucle actual y transfiere el control a la siguiente instrucción después del bucle:

for (let i = 1; i <= 10; i++) {
  if (i === 5) {
    break;  // Sale del bucle cuando i es 5
  }
  console.log(i);
}
// Salida: 1, 2, 3, 4

continue

La declaración continue salta la iteración actual y continúa con la siguiente:

for (let i = 1; i <= 5; i++) {
  if (i === 3) {
    continue;  // Salta la iteración cuando i es 3
  }
  console.log(i);
}
// Salida: 1, 2, 4, 5

Etiquetas (labels)

Las etiquetas permiten identificar un bucle y referenciarlo en las instrucciones break o continue:

exteriorLoop: for (let i = 1; i <= 3; i++) {
  for (let j = 1; j <= 3; j++) {
    if (i === 2 && j === 2) {
      break exteriorLoop;  // Sale del bucle exterior
    }
    console.log(`i=${i}, j=${j}`);
  }
}
// Salida:
// i=1, j=1
// i=1, j=2
// i=1, j=3
// i=2, j=1

Nota: Las etiquetas se usan raramente y pueden hacer que el código sea más difícil de leer. Generalmente es mejor refactorizar el código para evitar su uso.

Manejo de errores con try...catch

El bloque try...catch permite manejar errores de forma elegante:

try {
  // Código que puede generar un error
  console.log(variableNoDefinida);
} catch (error) {
  // Código que se ejecuta si ocurre un error
  console.log("Se produjo un error:", error.message);
}
// Salida: Se produjo un error: variableNoDefinida is not defined

Bloque finally

El bloque finally se ejecuta siempre, independientemente de si se produjo un error o no:

try {
  console.log("Inicio del bloque try");
  // Generamos un error
  throw new Error("Error personalizado");
} catch (error) {
  console.log("Error capturado:", error.message);
} finally {
  console.log("Este bloque siempre se ejecuta");
}
// Salida:
// Inicio del bloque try
// Error capturado: Error personalizado
// Este bloque siempre se ejecuta

Lanzar errores personalizados

Puedes lanzar tus propios errores con la instrucción throw:

function dividir(a, b) {
  if (b === 0) {
    throw new Error("No se puede dividir por cero");
  }
  return a / b;
}

try {
  console.log(dividir(10, 0));
} catch (error) {
  console.log("Error al dividir:", error.message);
}
// Salida: Error al dividir: No se puede dividir por cero

Tipos de errores en JavaScript

JavaScript tiene varios tipos de errores predefinidos:

  • Error: Error genérico
  • SyntaxError: Error de sintaxis
  • ReferenceError: Referencia a una variable no definida
  • TypeError: Valor no del tipo esperado
  • RangeError: Valor fuera de rango
  • URIError: Error en funciones de codificación/decodificación URI
try {
  // ReferenceError
  console.log(variableInexistente);
} catch (error) {
  console.log(`${error.name}: ${error.message}`);
  // Salida: ReferenceError: variableInexistente is not defined
}

Mejores prácticas

  1. Usa llaves para todos los bloques, incluso los de una sola línea:
    // Mal
    if (condicion) hacer();
    
    // Bien
    if (condicion) {
      hacer();
    }
    
  2. Evita bucles infinitos asegurándote de que la condición eventualmente sea falsa:
    // Mal (bucle infinito)
    for (let i = 0; i < 10; i--) {
      // Código
    }
    
  3. Usa for...of para arrays en lugar de for...in:
    // Preferible
    for (const elemento of array) {
      // Código
    }
    
  4. Maneja siempre los errores para evitar que tu aplicación se detenga:
    // Bien
    try {
      // Código que puede fallar
    } catch (error) {
      console.error("Error:", error);
      // Manejo del error
    }
    
  5. Evita anidar demasiados niveles de estructuras de control:
    // Evita esto
    if (condicion1) {
      if (condicion2) {
        if (condicion3) {
          // Código
        }
      }
    }
    
Operadores y Expresiones
Aprende a utilizar los diferentes tipos de operadores en Jav...
Funciones y Scope
Aprende a crear y utilizar funciones en JavaScript, comprend...

Conceptos Básicos de HTML

Aprende los conceptos básicos de HTML

Conceptos Básicos de CSS

Aprende los conceptos básicos de CSS

Conceptos Básicos SQL

Aprende los conceptos básicos de SQL

Conceptos Básicos de GIT

Aprende los conceptos básicos de GIT

Conceptos Básicos de Python

Aprende los conceptos básicos de Python

Conceptos Básicos de UML

Aprende los conceptos básicos de UML

Refuerzo Academico de Herramientas de Productividad 2025