Gramatica
4. La gramática:
A. Condicionales
El orden en que se ejecutan las instrucciones de un programa es, por defecto, secuencial, ejecutando instrucción tras instrucción. Así un programa se escribirá como una sucesión de instrucciones o sentencias, utilizando un punto y coma para indicar el final de la instrucción.
Pueden agruparse una serie de sentencias en un bloque encerrándolas entre llaves. A veces es necesario alterar este orden para ello se utilizan las instrucciones de control: condicionales, selección y bucles. Serán las sentencias condicionales las primeras que veremos.
Una sentencia condicional es una instrucción en la que se hace una comparación y según el resultado verdadero o falso ( true o false ) de la misma el programa seguirá ejecutando una u otra instrucciones.
La condiconal mas simple que podemos escribir es aquella que ejecuta u omite una serie de sentencias dependiendo de si la comprobación da verdadero o falso. La sintaxis de esta sentencia es.
if (condición) {bloque a ejecutar si la condición es cierta}
else
{bloque a ejecutar si la condición es falsa}
Si omitimos la parte del else tendremos una condicional simple. Esta sintaxis en algunos casos puede simplificarse utilizando la siguiente forma:
(condición)? {bloque si cierta} : {bloque si falsa}
En el siguiente ejemplo evitamos realizar una división por cero
if (div == 0)
logger.wearn('No se puede dividir por 0');
else
coc = num / div;
Otro ejemplo usando la segunda forma:
cad = (num >= 0)? '+' : '-';
En este ejemplo cad tomará el valor + si num es positivo o cero y el - si es negativo.
Las sentencias if pueden anidarse, es decir, dentro de una sentencia if pueden meterse mas sentencias if. Las condiciones pueden ser sencillas como en estos ejemplos o pueden enlazarse usando los operadores && y || (AND y OR lógicos). Veamos un ejemplo en el que comprobamos si un número está comprendido entre 1 y 5:
if (num>=1) && (num < 5) {
lista[indice] = 'Muy bajo';
bajos++;
}
indice++;
En este ejemplo si num está entre 1 y 5 (excluido) se anota en una lista las palabras 'Muy bajo' y se incrementa la variable bajos. Como vemos no se ha usado la parte de else y como se deben ejecutar mas de una sentencia las hemos encerrado entre llaves. Si num no cumple la condición el programa se salta este bloque. En cualquier caso la siguiente instrucción que se ejecute tras el condicional será la que incrementa el valor de indice.
B. Selección Múltiple
La estructura condicional permitía a lo sumo elegir entre dos posibles caminos en la ejecución de un programa: si la condición era cierta se ejecuta un bloque y si no se ejecuta otro.
Pero pueden existir casos en los que el programa deba tener mas de dos alternativas, por ejemplo si queremos un programa que presente un título en un idioma de cuatro posibles. Esto puede solucionarse mediante varios if anidados, siguiendo el ejemplo tenemos que elegir entre idiomas: castellano, ingles, francés y alemán.
if (idioma == 'castellano') {
SendCast();
} else if (idioma == 'ingles') {
SendIng();
} else if (idioma == 'frances') {
SendFran();
} else if (idioma == 'alemán') {
SendAlem();
} else {
error('idioma no presente');
}
Como vemos resulta un código bastante complejo. Para estos casos disponemos de la sentencia switch...case...default, de selección múltiple. El ejemplo anterior quedaría:
switch (idioma) {
case 'castellano':
AendCast();
break;
case 'ingles':
SendIng();
break;
case 'frances':
SendFran();
break;
case 'alemán':
SendAlem();
break;
default:
error('Idioma no presente');
}
Durante la ejecución se compara la variable idioma con cada uno de los posibles valores y cuando coincidan ejecuta el código correspondiente. La instrucción break pone fin al bloque y hace que el programa salte a la instrucción siguiente a la sentencia switch(), si se omite el programa continuaría con la siguiente comparación. La sección del default es opcional, su finalidad es ejecutar algún código cuando ninguna de las condiciones se cumpla.
C. Bucles
A veces es necesario repetir un mismo conjunto de sentencias varias veces. Por ejemplo para borrar todos los elementos de un array simplemente debemos hacer delete en cada uno de ellos, es una sentencia que se repetirá tantas veces como largo sea el array. Este es un típico trabajo para las estructuras repetitivas o bucles. En esencia la ejecución de un bucle consiste en ejecutar repetidas veces una misma parte del programa (cuerpo del bucle) hasta que se cumpla una determinada condición, en cuyo caso se acaba la repetición y el programa continúa con su flujo normal. Existen varias sentencias de bucles: while (condición) {... } , do {...} until (condicion) y for(contador; condición; modcont){...}.
Sentencia while
En esta estructura el programa primero comprueba la condición: si es cierta pasa a ejecutar el cuerpo del bucle, y si es falsa pasa a la instrucción siguiente a la sentencia while. Como siempre un ejemplo lo aclarará todo:
let lista = new Array(10);
let ind = 0;
while (ind < 10) {
lista[ind] = '0';
ind++;
}
En este ejemplo mientras que el valor almacenado en ind sea menor que 10 (la longitud del array ) irá almacenando en cada elemento del array lista un 0 e incrementando el valor de ind. Cuando este valor sea 10 el programa no entrará en el cuerpo del bucle. Si no se incrementara el valor de ind el bucle no acabaría nunca, el programa quedaría ejecutando indefinidamente el cuerpo del bucle.
Sentencia do...while
Se trata de un bucle en el que la condición se comprueba tras la primera iteración, es decir que el cuerpo del bucle se ejecuta al menos una vez. El ejemplo anterior quedaría como sigue:
let lista = new Array(10);
let ind = 0;
do {
lista[ind] = '0';
ind++;
} while (ind < 10)
Como vemos aquí no son imprescindibles las llaves para encerar el cuerpo del bucle. No está contemplada en el standard ECMA 1.5.
Sentencia for
Esta sentencia utiliza una variable de control a modo de contador para controlar la repetición del cuerpo del bucle. La sentencia da un valor inicial a este contador y en cada iteración lo modifica según le indiquemos y comprueba la condición, si se cumple ejecuta el cuerpo del bucle, si no lo salta y continúa por la siguiente sentencia. Vemos el ejemplo anterior usando esta sentencia:
let lista = new Array(10);
for (let ind = 0; ind < 10; ind++) {
lista[ind] = '0';
}
Como vemos el cuerpo del bucle no incrementa la variable ind , esto se indica en la cabecera de la sentencia. Este código hace exactamente lo mismo que el anterior.
Sentencia for ... in
Se trata de una variante de la sentencia for utilizada para iterar o recorrer todos los elementos de un objeto o de un array. Usa una variable de control que en cada iteración toma el valor del elemento del objeto recorrido. Por ejemplo si pruebas este código podrás ver todos los elementos del objeto document:
for (let item in document) {
logger.warn(item);
}
Con una matriz la variable de control toma el valor de los índices de la matriz, no su contenido.
D. Ruptura de Bucles
Aunque procuremos usara una programación estructura alguna vez puede ser necesario interrumpir la repetición de un bucle o forzar una iteración del mismo, esto puede lograrse mediante las sentencias break y continue. Son sentencias aplicables a cualquiera de las estructuras de bucle en JavaScript.
break
La sentencia break interrumpe la iteración actual y envía al programa a la instrucción que sigue al bucle.
let lista = new Array ('a','b','c','z','x','f');
let item ;
for (item in lista) {
if (lista[item] == 'z') {
break;
}
logger.warn(lista[item]);
}
Este ejemplo escribiría el contenido del array lista hasta encontrar una letra z.
continue
La sentencia continue interrumpe la iteración actual y envía al programa a la comprobación de la condición, si esta es cierta continúa con la siguiente iteración.
let lista = new Array ('a','b','c','z','x','f');
let item ;
for (item in lista) {
if (lista[item] == 'z') {
continue;
}
logger.warn(lista[item]);
}
Este ejemplo escribiría el contenido del array saltándose la letra z.