Estructuras de Control
Aprende a controlar el flujo de ejecución en JavaScript mediante condicionales, bucles y manejo de errores.
Cristian Escalante
Última actualización: 19 de abril de 2025
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
ofalse
) - 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:
- Inicialización:
let i = 1
(se ejecuta una vez al principio) - Condición:
i <= 5
(se evalúa antes de cada iteración) - 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éricoSyntaxError
: Error de sintaxisReferenceError
: Referencia a una variable no definidaTypeError
: Valor no del tipo esperadoRangeError
: Valor fuera de rangoURIError
: 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
- Usa llaves para todos los bloques, incluso los de una sola línea:
// Mal if (condicion) hacer(); // Bien if (condicion) { hacer(); }
- 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 }
- Usa
for...of
para arrays en lugar defor...in
:// Preferible for (const elemento of array) { // Código }
- 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 }
- Evita anidar demasiados niveles de estructuras de control:
// Evita esto if (condicion1) { if (condicion2) { if (condicion3) { // Código } } }