Porque NO deberías usar FiB en Javascript

FiB (Function Declaration in Blocks) es un concepto que describe una forma de declarar las funciónes en Javascript pero rara vez usada.

El concepto se traduce en español a: Declaración de funciones dentro de bloques.

El nombre lo dice todo. Pero de todas maneras, ilustremos lo obvio.

Un bloque en JS es cualquier parte del código que se encuentre dentro de las {}. Lo más común es que se usen con una expresión if, else, while, for, etc.

Por lo tanto este concepto aplicado se vería algo así:

if (true) {
    function example() {
        console.log("A great example");
    }
}

A lo mejor aunque no hayas declarado funciones dentro de un bloque esto no te sorprende. Al fin y al cabo es muy común declarar funciones por todo el código de JS, ya sea en el global o en algún local scope. (¿Necesitas repasar acerca de los scopes? No te preocupes puedese hacerlo hasta saciarte aquí).

No obstante el comportamiento de las FiBs es uno de los pocos que cambia dependiendo del ambiente que estés utilizando de Javascript.

Hagamos de cuenta que mandas a llamar la función del ejemplo anterior en tu navegador:

if (true) {
    function example() {
        console.log("A great example");
    }
}

example()

¿Crees que esta función se mande a llamar correctamente?

Si contestate que sí, eres igual de inocente que yo antes de aprender esto. (O bueno como todavía soy porque todavía se me olvida de vez en cuando)

La especificación de JS dice que las funciones declaradas dentro de un bloque, al igual que una variable declaradas con let/const, tienen alcance solo dentro de ese bloque. Por consiguiente es lógico pensar que el mandar a llamar example fuera de ese bloque va a lanzar un error. Sin embargo si corres esto en un navegador…

example() // A great example

¿Por qué pasa esto?

A los navegadores se les permite tener un comportamiento diferente al de la especificación. Esto es por el cambio que hubo de ES5 a ES6. En esa actualización se introdujó el concepto de block scope. Previamente Javascript solo tenía global y local scopes.

Esto provoca que haya muchísimo código vivo en la web que espera que se pueda ejecutar código como el del ejemplo. Si los navegadores se comportaran como lo indica la especificación, incontables sitios morirían.

*Hay otras lugares donde puedes correr Javascript, pero el principal es el navegador así que es importante que conozcas esta clase de excepciones y que sepas porque se dan.


Pero problablemente al estar leyendo esto te estés tratando de imaginar. “¿En que escenario me serviría utilizar esto?”. Es una duda normal. Todo mundo al conocer este concepto tuvo esta duda y todo el que la este aprendiendo la tendrá.

La respuesta es…NUNCA!!!

Pero es más fácil entender porque conociendo primero que es lo que traen a la mesa.

Las FiB son buenas (al menos en concepto) porque pueden ayudar a optimizar tu código.

Veamos un ejemplo:

const value = 'sa'

if(typeof value === 'string' ) {
    function addTenToString(value) {
        return value + '10'
    }

    addTenToString()
} else {
    function addTenToNumber(value) {
        return value + 10
    }

    addTenToNumber()
}

Lo que hace este código es que está creando condicionalmente las funciones. Si el valor de la variable es un cadena de texto entonces se crea una función que le concatena un ’10’ a el valor que le pases. Si en cambio el valor es un número entonces la función que se crea le suma 10 al mismo valor.

Podría decirse que esto es más óptimo para la memoria porque la función creada que se mantiene en memoria tiene menos lógica que manejar. La alternativa al no usar una FiB sería crear una sola función con esta lógica condicional dentro. Dicha función sería más compleja y por ende ocuparía más espacio.

Ok pero…¿en verdad esto ayuda a optimizar mucho el manejo de memoria? No realmente. Y si estás siguiendo buenas prácticas a la hora de escribir tu código (como alta cohesión y bajo acomplamiento entre otros) mucho menos.

Por otro lado el precio a pagar por hacer uso de estas funciones es bastante alto. Se dificulta muchísimo el proceso de debuggeo.

Cuando llegues a tener un error en tu base de código,siempre tendrás que averiguar de donde se origina. Pero si estas usando FiBs, tendrás que hacer doble trabajo de averiguación. El error ocurrió ¿porque la función que estas usando tiene un error en su lógica? ¿o porque la lógica que utilizaste a la hora de seleccionar la función a crear es la que está mal?

¿En verdad vale la pena hacer tu código más confuso, más difícil de debuggear y de entender por una negligible mejora en el manejo de memoria? Yo opino que no, y por eso abogo porque nunca lo uses.

¿Entonces? ¿Para qué aprender de algo que no vale la pena usar?

Es bueno conocer que existe y que usos tiene. Así nadie te cuentea y te convence de algo que no es una buena idea.