Saltar al contenido

LDP | §1.7 - Decisión e iteración

§1.6 Funciones

Con referencia a los tres ladrillos básicos de la programación, hemos usado hasta ahora sólo el primero (secuencia), a través de una sucesión de sentencias JavaScript, sean en la misma línea o en líneas separadas. Es hora de ver en este lenguaje cómo se escriben los otros dos.

Decisión

JavaScript posee dos palabras reservadas para programar una decisión (también llamada condicional): if y else. La estructura general es:

if (condición a evaluar) {
    // código a ejecutar si la condición se evalúa como verdadera
}

O bien:

if (condición a evaluar) {
    // código a ejecutar si la condición se evalúa como verdadera
} else {
    // código a ejecutar si la condición se evalúa como falsa
}

Es decir, una decisión tiene la siguiente forma:

  • La palabra reservada if, que introduce la decisión;
  • Le sigue la condición a evaluar entre paréntesis. Si bien lo usual es que esta expresión tenga un valor lógico true o false, JavaScript le asignará uno de estos dos valores aunque la expresión no sea del tipo lógico. Por ejemplo:
    • Si la expresión es numérica, se evaluará como false si es igual a cero, o como true en cualquier otro caso;
    • Si la expresión es de tipo string, se evaluará como false si es la cadena vacía "", o como true en caso contrario;
    • Una expresión de tipo arreglo o de tipo objeto siempre es verdadera (true);
    • Las constantes predefinidas null, NaN y undefined siempre son falsas (false).
  • A continuación un bloque entre llaves que encierran las instrucciones a ejecutar si la condición se evalúa como verdadera. Las llaves pueden omitirse si sólo contienen una sentencia JavaScript, pero una buena práctica es utilizarlas siempre, ya que en ese caso puedo agregar posteriormente más sentencias sin tener que recordar que ahora debo también agregar las llaves.
  • Opcionalmente, si deseo tener un bloque de código que se ejecute cuando la condición no se cumple (se evalúa como false), debemos agregar la palabra reservada else seguido de un bloque de código a ejecutar en ese caso.

Una vez ejecutado uno de los dos bloques, según el resultado de la evaluación de la condición, la ejecución del programa sigue normalmente a partir del último bloque definido. Por ejemplo,

var x = prompt('Ingrese un número de hasta dos dígitos:');
if (x < 100) {
    alert('El número ingresado es ' + x);
} else {
    alert('¡Tu número tiene más de dos dígitos!');
}
alert('¡Gracias por participar!');

Según el número ingresado por el usuario, se ejecutará el primer alert o el segundo, pero en cualquier caso siempre se ejecutará el tercero dando las gracias, ya que está a continuación, por fuera de la decisión.

Operadores de comparación

Normalmente la condición de una instrucción if es algún tipo de comparación, para lo cual es útil tener a mano los operadores que nos permiten comparar variables y constantes entre si:

Operador Descripción
< Menor que (estricto)
<= Menor o igual que
> Mayor que (estricto)
>= Mayor o igual que
== Igual
!= Distinto
=== Idéntico (mismo valor y tipo)
!== No idéntico (distinto valor y/o tipo)

Debemos tener en cuenta lo siguiente:

  • Los cuatro primeros operadores de comparación, cuando se aplican a números, tienen el significado matemático habitual de orden numérico. Si se aplican a strings, el orden es alfabético. Por ejemplo,
    var a = "Juan";
    var b = "Pedro";
    var c = "María";
    var d = "Juan";
    // a < b es true 
    // a <= b es true
    // b < c es false 
    // b > a es true 
    // a < d es false 
    // a <= d es true
  • La comparación de igualdad (==) tiene un doble signo igual para diferenciarla de la simple asignación (=). Notar la diferencia entre ambos signos en el siguiente ejemplo:
    var n = prompt("Ingrese cantidad de items a comprar:");
    if (n == 0) {
        alert("¡Ud. no ha comprado nada!");
    }
  • Si las expresiones a comparar no son del mismo tipo (números comparados a strings), JavaScript convierte previamente el string a número. Por ejemplo,
    var a = 1;
    var b = "2";
    var c = 2;
    // b < a es false (b se convierte al número 2 previo a la comparación)
    // b == c es true (numéricamente son iguales)
  • En cambio, cuando al comparar queremos estar seguros que ambos son del mismo tipo, además del mismo valor, utilizamos la comparación de identidad ===. Usando el mismo ejemplo,
    var b = "2";
    var c = 2;
    var d = 1 + 1;
    // b == c es true (numéricamente son iguales)
    // b === c es false (no son del mismo tipo)
    // c === d es true (mismo tipo y valor)
  • Por último los operadores de igualdad e identidad tienen sus opuestos; != (no igual) y !== (no idéntico). Es decir:
    var b = "2";
    var c = 2;
    var d = 1 + 1;
    // b != c es false (numéricamente son iguales)
    // b !== c es true (no son del mismo tipo)
    // c !== d es false (mismo tipo y valor)

Iteración

Una iteración puede lograrse en JavaScript mediante tres estructuras diferentes, cada una mejor adaptada a una situación particular, aunque equivalentes entre sí.

for

Esta estructura tiene la siguiente forma:

for (inicialización; condición de continuación; actualización) {
    // código a ejecutar en cada iteración
}

Es decir, for requiere en principio tres expresiones, separadas por punto y coma, con el siguiente significado:

  • La primera expresión (inicialización) sirve para definir una o más variables al comenzar con la iteración. Esta expresión es ejecutada una sola vez, antes de la primera de las iteraciones. Lo habitual en este tipo de iteración es contar al menos con una variable de control cuyo valor cambia en cada iteración; en ese caso, esta primera expresión nos permite definir su valor inicial;
  • La segunda expresión (condición de continuación) se evalúa a un valor lógico antes de cada iteración para definir si la repetición debe continuar. Si el resultado es verdadero (true), la siguiente iteración se realiza; de lo contrario, toda la iteración termina;
  • La tercera expresión (actualización) es una sentencia que se ejecuta al finalizar cada iteración. Tìpicamente sirve para cambiar el valor de la variable de control y prepararla para la iteración siguiente.

Luego debe seguir un bloque entre llaves que contiene las instrucciones a ejecutar en cada iteración.

Veamos un ejemplo. Supongamos que simplemente queremos mostrar en la consola de JavaScript los números consecutivos de 10 a 20. El siguiente código serviría para ese propósito:

for (var contador = 10; contador <= 20; contador = contador + 1) {
    console.log(contador);
}

Expliquemos su funcionamiento:

  1. En la primera expresión definimos la variable contador inicializándola en 10, es decir, el primer número a mostrar;
  2. Inmediatamente JavaScript evalúa la segunda expresión. Si resulta verdadera (true), la siguiente iteración (en este momento es la primera) comienza;
  3. Se ejecuta en este caso la única instrucción console.log(contador), que al tener en este momento la variable contador el valor 10, es el valor mostrado en la consola;
  4. No habiendo más instrucciones, JavaScript ejecuta la tercera expresión del for, lo que en nuestro caso incrementará el valor de la variable contador en 1, quedando así en 11;
  5. Se pasa a la siguiente iteración, para lo cual JavaScript evalua la segunda expresión nuevamente para decidir si continuar. Como la condición se cumple (contador vale 11 y es menor a 20) se inicia la segunda iteración, y así sucesivamente.

while

Una segunda forma de realizar una iteración en JavaScript es mediante la palabra reservada while ("mientras" en inglés). Veamos su estructura:

while (codición de continuación) {
    // código a ejecutar en cada iteración
}

A primera vista parece más simple, y lo es: while sólo nos ofrece repetir un bloque de código mientras una condición sea verdadera. Es responsabilidad del programador agregar el código  necesario para mantener actualizada la expresión que se usa como condición, y que eventualmente la iteración termine alguna vez.

Veamos el mismo ejemplo anterior mediante el uso de while:

var contador = 10;
while (contador <= 20) {
    console.log(contador);
    contador = contador + 1;
}

Como vemos, la inicialización y el incremento de la variable contador deben hacerse explícitamente mediante sus respectivas sentencias JavaScript para que la iteración funcione.

do ... while

Tanto en for como en while, la condición de continuación siempre es evaluada al comienzo de cada iteración (lo que se denomina iteración con pregunta al principio), lo que permite que en algún caso no se realice ninguna iteración en absoluto si se da el caso que la condición es falsa desde el principio. Hay casos donde la naturaleza del problema exige que la iteración se realice al menos una vez; de ser así, tiene más sentido preguntar por la condición de continuación al finalizar cada iteración. Es aquí donde esta variante presta su utilidad. Su estructura es la siguiente:

do {
    // código a ejecutar en cada iteración
} while (condición de continuación);

Es decir, se utiliza la palabra reservada do, seguida del bloque de código a iterar, para terminar con un while y su respectiva condición de continuación. Este tipo de iteración se conoce como iteración con pregunta al final. Como en los otros casos, reescribamos el mismo ejemplo con esta variante:

var contador = 10;
do {
    console.log(contador);
    contador = contador + 1;
} while (contador <= 20);

Si bien en estos tres ejemplos utilizando for, while y do ... while el resultado es el mismo, analicemos qué sucede si queremos contar desde 10 hasta otro número. Como es evidente, basta con modificar la constante 20 con el valor deseado, por ejemplo un número ingresado por un usuario. Pero, ¿qué sucede si la persona ingresa 9? Se supone que no debo contar nada. Mientras for y while responderían correctamente al no iterar, do ... while realizaría una iteración y mostraría 10 en la consola, que no es lo esperado en ese caso.

El siguiente cuadro muestra una sugerencia para orientarse en la elección de cada instrucción de iteración, recordando que la mayor parte de las veces es posible reescribir un tipo de iteración en otro:

Iteración Tipo Aplicación típica
for Iteración con pregunta al principio Recorrido por una serie de valores conocidos en tiempo de ejecución
while Iteración con pregunta al principio Búsqueda de una condición que requiere una cantidad (cero o más) de repeticiones no necesariamente conocidos en tiempo de ejecución
do ... while Iteración con pregunta al final Búsqueda de una condición que requiere una cantidad (uno o más) de repeticiones no necesariamente conocidos en tiempo de ejecución

Interrupción prematura de una iteración

En ocasiones durante la ejecución del código de la iteración ocurre algo que hace innecesario seguir adelante con el resto de las iteraciones. Supongamos que tenemos una lista de palabras (que en JavaScript escribiríamos como un arreglo) y deseamos saber si cierta palabra está en la lista. Podemos recorrer el arreglo para ver si la palabra se encuentra, pero una vez encontrada no haría falta seguir. Veamos el siguiente código;

var invitados = ['Pablo', 'Manuel', 'Ana', 'Mario', 'Mirta', 'Analía', 'Raúl', 'Laura', 'Gabriel'];
var nombre = prompt("Ingrese un nombre para saber si es un invitado:");
var encontrado = false;
for (var i = 0; i < 9; i++) {
    if (nombre == invitados[i]) {
        encontrado = true;
        break;
    }
}
if (encontrado) {
    alert(nombre + " es un invitado");
} else {
    alert(nombre + " no es un invitado");
}

El código funciona de la siguiente forma. Inicialmente tenemos una lista (arreglo) de invitados y solicitamos al usuario un nombre. Definimos una variable encontrado con el valor inicial false que nos servirá para indicar si encontramos el nombre en la lista, para lo cual iteramos comparando nombre con cada palabra en la lista (invitados[i]). Si encontramos una coincidencia, establecemos la variable encontrado a true; pero en ese caso no tenemos necesidad de seguir recorriendo la lista. La palabra reservada break sirve para eso: interrumpe anticipadamente las iteraciones y pasa la ejecución a la siguiente instrucción posterior al for, en este caso el if final, el cual usamos para informar al usuario si encontramos el nombre o no.

El uso de break no está limitado a una iteración for; también puede emplearse dentro de un while o un do ... while.

 

§1.8 Objetos >