5. Control de Flujo
Uno de los elementos más básicos de cualquier lenguaje de programación es el elegir cuáles instrucciones ejecutar con base en la evaluación de una condición lógica. En JavaScript, los dos mecanismos principales son las declaraciones condicionales if … else y switch.
La estructura del if... else es muy fácil de interpretar. Por ejemplo:
En el segmento de código arriba se observa como la condición a evaluar es si la variable r es mayor o igual a 5. De ser cierto, se ejecuta el primer bloque de código que comunica que ya se han contestado al menos 5 preguntas. De lo contrario, se ejecuta el segundo bloque de código que comunica que aún falta preguntas por contestar e indica cuantas.
Es posible “encadenar” evaluaciones para tomar decisiones más complejas sin tener que recurrir a múltiples condiciones if … else binarias cuya condición a evaluar contiene la complejidad de múltiples OR y AND.
Así entonces, para agregarle a la estructura lógica original una condición que evalúe la posibilidad de que no exista ni una respuesta(r=0), versus cuando existe al menos una respuesta. Se puede establecer así:
Ahora, cuando la toma de decisiones involucra diferentes posibles valores de una misma variable, es más sencillo plantear el código como una declaración switch así:
Como se observa en el ejemplo, usando switch es posible ser muy específicos en cuanto a cuál valor de la variable r desencadena la ejecución de cada bloque de código. Si el valor en r no coincide con alguno de los “case”, el “switch” toma la opción "default”.
Mas detalles: https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals
Bucles e iteraciones (loops):
Los bucles o "loops” son otro elemento esencial de los lenguajes de programación pues permiten ejecutar un bloque de código repetidamente y ofrecen varias formas de definir cuantas veces hacerlo (for), hasta cuando hacerlo (do while) o mientras que condición se cumpla seguirlo haciendo (while). También ofrecen mecanismos para inmediatamente terminar la iteración basada en alguna condición lógica dentro del bloque de código con las declaraciones “break” y “continue”.
Continuando con la idea de requerir del usuario responder 5 preguntas. Oserve con atención este ejemplo, se obtendrán 5 respuestas al llamar a la función “hacer_pregunta()”. Esta función toma el valor de la variable de control del for y la multiplica por 10. Aunque esta operación no tiene relación con hacer preguntas, sirve para que se observe la ejecución de la función. Ya que la sección que se está analizando es la estructura del bucle for.
Note como los componentes de control se encuentran dentro de los paréntesis y están separados por punto y coma ( ; ). Primera parte (let num_preguntas = 1; aquí se establece el valor inicial de la variable que lleva el conteo de las repeticiones (contador). Tradicionalmente se inicia en 1, pero el valor se puede cambiar si es necesario. Segunda parte num_preguntas <= 5;la condición de control. Acá se compara el contador contra el valor de control. Si la respuesta a esta condición es true, se ejecuta el bloque de código. De lo contrario, se termina el ciclo. Tercera parte num_preguntas++)el incremento. Llamado así ya que en la mayoría de los casos se lleva un conteo de 1 en 1. Por lo tanto, basta con sumar al valor del contador +1 para avanzar. Sin embargo es posible modificar la variable contador de muchas formas. Lo importante es modificarla de manera que eventualmente la condición de control de repeticiones obtenga false como resultado de la evaluación y dentenga el bucle.
Entonces al ejecutar el código arriba ya sea en la consola de node.js o poniéndolo en un archivo tipo .js y ejecutándolo con el comando node, se obtendrá la misma solución en la consola:
Otra forma de definir este bucle entonces es inicializar la variable num_preguntas fuera del bucle y usar “do...while” de esta forma. Observe que las instrucciones dentro del bloque son las mismas.
Al ejecutar la versión basada en “while” se obtiene el mismo resultado porque la lógica es exactamente las misma, solo que definida ligeramente diferente usando el mecanismo “do...while”. La versión de este mismo bucle usando solo “while” básicamente cambia el orden de evaluación de cuando seguir o salir del bucle así:
Para ilustrar el uso de las declaraciones “continue” y "break” observe la siguiente modificación al bucle y el resultado:
Como se puede ver en el resultado, cuando el resultado es 20, le ejecución de la declaración “continue” finaliza únicamente la ejecución de la iteración en curso (en este caso respuesta 2 es 20). La ejecución omite ejecutar el bloque de instrucciones y solo salta de regreso al principio del bucle, a la evaluación de la condición de control y continúa desde ahí. En esta ocasión, lo único que no se termina de ejecutar del bucle es el imprimir que la respuesta es válida. La declaración "break” se ejecuta si la respuesta es 40 y termina la ejecución del bucle, rompe por completo la evaluación de la condición de control y pasa a la instrucción que sigue fuera del bloque de instrucciones del ciclo. Aquí nunca llega a la pregunta 5.
Más detalles sobre las estructuras de repetición acá: https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Loops_and_iteration
Funciones
Uno de los mecanismos más comunes para reutilizar código son las funciones. Es por ello que están implementados en prácticamente todos los lenguajes de programación. Una función encapsula un grupo de código que hace una tarea especifica y se le asigna un nombre y se le definen parámetros para poder ser invocado desde otras partes del código. Las funciones pueden devolver o “retornar” valores, pero es opcional.
En JavaScript, las funciones se declaran usando la palabra clave “function” seguida de paréntesis y opcionalmente parámetros dentro de los paréntesis separados por comas. El nombre de la función tiene las mismas limitantes que el nombre de las variables: solo puede contener letras, dígitos, barra baja y símbolo de dólar. Después de la declaración de la función, se debe especificar el código a ejecutar rodeado de corchetes.
Seguidamente un ejemplo:
El código dentro de la función va a considerar los parámetros como variables locales y va a ser ejecutado cuando una de las siguientes tres condiciones se dé:
Al ocurrir un evento asociado a la función mediante la especificación de un “callback” u otro mecanismo.
Al ser invocado explícitamente desde otra parte del código.
Automáticamente (invocado por sí mismo)
Si una función usa la palabra clave “return” dentro del código, en ese momento termina la ejecución de la función y se retorna un valor hacia el elemento que invoco la función. Por ejemplo:
En JavaScript, las funciones se pueden pasar y asignar a variables como cualquier otro valor. Con solo obviar los paréntesis, se estará asignando un objeto que contiene la función en vez del valor que pueda calcular y retornar el valor.
Por ejemplo, si se le asigna a x la función sin los paréntesis:
El valor de X se podrá ver reflejado cuando se ejecute console.log(x) como:
Esta habilidad de pasar y asignar una función como un objeto es muy utilizada en varios aspectos de JavaScript como se verá más adelante.
Arrow Functions
Las «Arrow Functions» nos permiten definir una función de forma abreviada. Se llaman así, porque el se utilizan los símbolos de igual y mayor formando una flecha ( => arrow en inglés ). Por ejemplo:
Antes:
Después:
Más detalles acerca de funciones aquí: https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Functions