Hablemos de Inmutabilidad en JavaScript

Kike.pe
Zurvin

--

Hace poco un colega ninja en javascript me comentó sobre la inmutabilidad, así que decidí hacer un breve repaso del qué es y del por qué los desarrolladores master la usan.

Como ya es sabido la preservación de nuestros datos a lo largo de nuestra aplicación es muy importante. Si los datos mutan en algún lugar de nuestro desarrollo será mucho más difícil encontrar el error y mantener nuestra lógica tomará más tiempo del necesario. Esa no es la idea, ahí entra en juego la inmutabilidad en javascript, que en realidad no es propio de javascript sino que se puede usar en cualquier lenguaje con el paradigma de programación funcional, vi un ejemplo en Python y se aplicaba fácilmente.

Pero basta de texto, veamos un poco de código. Tenemos este objeto, el cual está presente en toda nuestra aplicación, este objeto debe ser inmutable, nadie debería cambiarlo porque afectaría a otras secciones y el debug sería un caos. Pero en este código el objeto Precios sí es mutable, como se ve en la salida Precios.parlantes = 50 sí agregó ese campo en nuestro objeto.

Más de uno va a decir pero es que ese objeto esta declarado como let y yo usaría const. Es válido pero NO, const sólo hace inmutable la asignación a la variable, mas no de un campo de nuestro objeto. Así que, si en el código anterior cambio let por const igual se agregaría parlantes a nuestro objeto Precios

Mi primer contacto con la teoría de inmutabilidad fue con una característica de ES6 que se aplica a objetos y es el método Object.freeze(), veamos un ejemplo:

Hemos agregado el método Object.freeze y le pasamos como parámetro nuestro objeto, de esta manera vemos que en la salida no se agregó el campo parlantes:50 ya que freeze() congela los datos del objeto que recibe. Noten que agregue ‘use strict’ en la primera línea para que el intérprete de javascript nos dé una alerta cada vez que alguien intente mutar nuestro objeto.

Pero este método tiene una desventaja y es que no vuelve inmutable los objetos anidados. Se resuelve volviendo a invocar el método en cada objeto nuevo pero nuestro código tiende a extenderse demasiado y no es la idea.

Hay librerías que congelan todo nuestro objeto, una muy conocida es deep-freeze:

npm i deep-freeze

Recalcar la importancia de mantener a salvo nuestros datos en nuestra aplicación y si se requiere hacer cambios hacerlo bajo copias, nunca modificando la data original. Esto es básico en React por ejemplo con su teoría de una única fuente de verdad.

Un ejemplo más con arrays y usando el operador spread del que hablé en mi post anterior.

Como dije anteriormente, si nunca debemos modificar el estado original de nuestros datos. Es óptimo llenar un espacio en memoria por cada cambio?Créanme que no soy el primero ni el último en preguntarse eso.

Investigando más a fondo sobre este tema me topé con nuevos términos y conceptos. Sobre todo en cómo debemos estructurar nuestros datos para lograr una persistencia funcional. Por ejemplo Array Mapped Trie y Hash Array Mapped Trie usan una teoría conocida como Estructura compartida.

Pero traduzcamos esto al español y con manzanitas:

Veamos el ejemplo de un array. Lo que hacemos al modificar el array no es duplicar todo, sino que hacemos una referencia al cambio, así luego solo comprobamos las referencias para ver los cambios y siempre podemos volver a la fuente inicial con nuestra data inicial completa.

Gráficamente podemos diferenciarlo así. En este ejemplo con un array mutable podemos ver que el array inicial cambió su estado y el valor D ya no es accesible más.

En esta otra imagen se ve más claro la teoría de inmutabilidad, el array inicial nunca cambia, sino que se crea una copia alterna tomando los valores iniciales del array X y solo agregando el elemento E para generar un nuevo array, así el array inicial se mantiene siempre con el mismo valor; es inmutable.

Ahora que tenemos un mejor panorama, esto parece un tanto difícil de aplicar a nuestros proyectos, y en parte es cierto, es por ello que existe una librería que también nos ayudará con esto: Immutable.js

Esta librería simplifica el trabajo para que nosotros solo pensemos en cómo trabajar con los datos sin preocuparnos de lo que pase por detrás.

Así por ejemplo podemos pasarle a immutable nuestro objeto y usar sus métodos .set() y .get() y como vemos en el siguiente código los datos iniciales nunca cambian.

Como cierre de este post, solo quiero añadir que si bien esta teoría parece un poco compleja, en la práctica no lo es tanto, con la ayuda de librerías y una buena estructura de nuestros datos, podremos sacar adelante un proyecto robusto y escalable.

Como dije mi primer contacto con este concepto fue con React, con el cual tuve mas de un dolor de cabeza cuando implementé Redux. Pero una vez que lo dominas ves el mundo de otra manera, actualmente lo veo también con Angular, y es que la data es lo mas importante en nuestras aplicaciones y la inmutabilidad complementa mucho a tener un código limpio y mantenible.

Sin más, enjoy code!

--

--

Kike.pe
Zurvin
Editor for

Fullstack Developer Analyst. Javascript lover and on the path of continuous learning.