Sección 3: JavaScript avanzado

Lección 7: Conceptos avanzados de funciones

En esta lección vamos a tratar sobre conceptos avanzados de funciones. El primer concepto que veremos es el de closure (clausura). La clausura es una característica de JavaScript, donde una función interna tiene acceso a las variables de otra función externa que la contiene.

La clausura posee tres cadenas de scopes (alcances):

- Posee acceso a su propio scope (alcance), osea a las variables que están definidas entre sus llaves { }.

- Posee acceso a las variables de la función externa que la contiene.

- Posee acceso a las variables globales.

Veamos un ejemplo:

En el ejemplo tenemos dos funciones:

- La función externa que posee una variable llamada b, y retorna la función interna.

- La función interna que posee una variable llamada a, y accede a la variable b de la función externa.

El scope (alcance) de la variable b está limitado a la función externa, y el scope (alcance) de la variable a está limitado a la función interna. Sin embargo, la función interna puede acceder a las variables de la función que la contiene gracias a la clausura.

En otras palabras, la función interna preserva la cadena de scopes (alcances) de la función que la contiene al momento que la función externa es ejecutada, y es por ello que puede acceder a sus variables.

En nuestro ejemplo, la función interna ha preservado el valor de b=10 cuando la función externa ha sido ejecutada, y es por ello que podemos realizar correctamente el cálculo a + b, o 20 + 30.

Podemos verificar lo anteriormente descripto añadiendo unas líneas de código a nuestro ejemplo:

Veamos en nuestra consola la ejecución de este código:

Podemos apreciar que el código nos retorno la función interna. A su vez dentro de esta función podemos apreciar que posee tres scopes (alcances): el de la propia función, el de la función que la contiene, y el global.

Ahora veamos un nuevo concepto de JavaScript: el currying, el cual es un proceso de convertir una función que toma múltiples argumentos en una función que toma un argumento por vez. Veámoslo en un ejemplo:

El currying implica cambiar la función del ejemplo anterior para que acepte un parámetro por vez:

Esto quizás parezca confuso, pero pensemos en cada una de las dos flechas como una función. Intentemos ahora llamar a multiplicar2 pasándole un solo argumento:

Vemos que obtenemos una función que acepta un parámetro b y retorna a * b. Por lo tanto que podemos inferir que el parámetro a ha sido reemplaza por el valor 3.

Ahora pasémosle dos argumentos a esta función para comprobar que funciona bien:

Ahora la pregunta es, ¿para qué necesitamos el currying? Debido a que ahora es más extensible. Por ejemplo podemos hacer lo siguiente:

De esta manera, cada vez que quiera multiplicar un número por 5, puedo hacer uso de la función multiplicarPor5.

Ahora veremos un nuevo concepto: compose (composición). Gracias a la composición podemos componer dos funciones para formar una tercera función. Veamos un ejemplo:

Analicemos el código que acabamos de ejecutar para entender porqué retorna 7. El parámetro a es reemplazado por el valor 5, y su vez tanto f como g son reemplazadas por la función incremento. Podemos deir que nuestra función queda compuesta de la siguiente manera f(g(5)) o también de la siguiente manera incremento(incremento(5)).

Si comenzamos a resolver la primera función de incremento obtenemos el siguiente resultado incremento(6) ya que incremento(5) es igual a 6. Finalmente si resolvemos incremento(6) obtenemos el valor 7.

Para terminar esta lección, veremos una de las cosas más importantes que podemos hacer como desarrolladores web cuando creamos código, y esto es el evitar los efectos colaterales y promover la pureza funcional.

¿Qué significa esto? Los efectos colaterales son aquellas acciones que ocurren dentro de una función, que interactúan con el entorno de la función, ya sea leyendo o modificando variables definidas fuera de la función. Veamos un ejemplo:

La función b afecta su mundo exterior. Es una buena práctica evitar estos efectos colaterales, y para hacerlo tenemos un concepto llamado pureza funcional. Para hacerlo debemos lograr eliminar todas los efectos colaterales de nuestras funciones y asegurarnos de que siempre retornan un valor.

¿Y cuál es el poder que aporta todo esto? De esta manera crearemos una función determinística, lo cual implica que si ingresamos los mismos argumentos, la función retornará siempre el mismo resultado. Eso es determinismo, y es un concepto clave para evitar errores en nuestros programas.

Bueno, eso fue todo por esta lección.

Nos vemos en la siguiente.

¡Adios!

Made with Slides.com