Entendiendo la Mutabilidad y la Re-asignación
Tags: javascript, mutability, beginners, programming
Published: 2024-06-02 22:18:04

Buenas, hoy quisiera hablar sobre un tema que puede ser confuso al iniciar en programación, especialmente en lenguajes como Javascript donde la diferencia es tan clara: La Mutabilidad y la Re-asignación.

Al igual que en otros lenguajes, Javascript permite la definición de variables en las cuales almacenar datos. Existen 3 palabras reservadas que nos sirven para definir variables: `var`, `let` y `const`, pero para este artículo, nos concentraremos en estas últimas 2, y ahondaremos en su relación con la mutabilidad y la reasignación.

- `let`: Permite definir una variable cuyo valor puede re-asignarse en cualquier momento.
- `const`: Permite definir una variable cuyo valor no puede re-asignarse, esa decir, una constante.

Estas definiciones, si bien son concisas, podrían no bastar para dar cuenta del impacto que tiene el uso de uno versus el otro en Javascript, pues en mi opinión, es necesario hacer énfasis primeramente en los conceptos de **re-asignación** y **mutabilidad** que conlleva el uso de una u otra palabra reservada. 

Para ello, nos remontaremos a cómo funciona la memoria en un computador: a grandes rasgos, e ignorando cierta cantidad de aspectos fundamentales sobre arquitectura de computadores, es la memoria RAM la que almacena los datos con los que vamos a trabajar. Estos datos tienen **direcciones** a través de las cuales accedemos a ellos. 

Veamos un ejemplo: supongamos que tenemos una memoria RAM de 8 bytes, por lo que si necesitáramos almacenar 1 byte, podríamos hacerlo en cualquiera de los 8 espacios distintos disponibles. Vamos a decir que estos espacios son **direcciones de memoria**, y los nombraremos del 0 al 7. 

Cuando declaramos la primera variable en nuestro código, digamos `x = 5`, el computador va a buscar un espacio de memoria disponible en nuestra RAM, digamos que en este caso es el espacio 0, y va a guardar allí el valor 5. Esto significa que la variable `x` va a **apuntar** a la dirección de memoria 0, porque en nuestra memoria RAM hemos guardado el número 5, pero nuestra variable `x` no contiene el número 5, sino que contiene la **dirección de memoria** donde se encuentra el número 5. 


![Memoria RAM de 8 bytes, con x apuntando a la dirección 0 y guardando el número 5.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8wal044ugk9ect08ir1s.png)
> Memoria RAM de 8 bytes, con `x` apuntando a la dirección 0 y guardando el número 5. 

Ahora bien, tenemos entonces variables que representan direcciones de memoria, y direcciones de memoria en donde se guardan datos. Estos datos pueden ser números, caracteres e incluso **punteros**. Para entender esto, primero vamos a definir el concepto de puntero:

- **Puntero:** es un dato que contiene una **dirección de memoria** de otro dato, por eso se dice que **apunta** hacia otra dirección de memoria.

Siguiendo con nuestro ejemplo, podemos guardar en la dirección 1 de la memoria un **puntero** hacia la dirección 2. Por lo tanto, si quisiéramos acceder al dato que se encuentra en la dirección 2, tendríamos que acceder primero a la dirección 1, que nos llevará a la dirección 2.

Supongamos que en la dirección 2 se almacena una **Lista** de 4 elementos `(7, 'a', 'c' y 9)`. Como ya no es un solo dato, vamos a utilizar más espacios de memoria: 4 bytes en total, desde el espacio 2 (el inicio) hasta el espacio 5 (el final). Entonces, resumiendo, en la dirección 0 de nuestra RAM tenemos el número 5, en la dirección 1 tendremos un puntero a la dirección 2, y en la dirección 2 una lista de 4 elementos:

![Memoria RAM de 8 bytes, con x apuntando a la dirección 0, un puntero en la dirección 1 apuntando a la dirección 2, y 4 elementos correspondientes a la lista que parte en la dirección 2 y termina en la dirección 5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r5cykxvicdghngzn4a3y.png)
> Memoria RAM de 8 bytes, con `x` apuntando a la dirección 0, un puntero en la dirección 1 apuntando a la dirección 2, y 4 elementos correspondientes a la lista que parte en la dirección 2 y termina en la dirección 5.

Teniendo este escenario en mente, vamos a definir los conceptos de **re-asignación** y **mutabilidad**. La **reasignación** es cuando queremos cambiar el valor **almacenado en la dirección de memoria** que representa nuestra variable. Es decir, la operación `x = 10` accedería a la dirección 0 y cambiaría el valor que allí se almacena de 5 a 10, lo que estaría **re-asignando** a la variable `x`. O bien, podríamos **re-asignar** la dirección de memoria 1 para que deje de almacenar la dirección de memoria 2, y de ahora en adelante guarde un número cualquiera en vez de un puntero. 

Por otro lado, diremos que la **mutabilidad** es la capacidad que tiene una variable de modificar su contenido **sin cambiar el valor** almacenado en la dirección de memoria que representa. Siguiendo la idea anterior, si tenemos una nueva variable `y` que representa la dirección de memoria 1 (que recordemos, almacena un puntero a la dirección de memoria 2, donde hay una lista), y queremos **modificar un elemento** de esa lista, podemos hacerlo sin cambiar el valor que se encuentra en la dirección de memoria 1. Esto significa que estaríamos **mutando** la variable `y`, ya que vamos a modificar un valor en otra dirección de memoria. Sin embargo, si ahora queremos que la variable `y` tenga el valor 3, la estaría **re-asignando** y no **mutando**. 

En resumen:

- **Re-asignación**: capacidad de una variable de cambiar el valor almacenado en la dirección de memoria a la que apunta.
- **Mutabilidad**: capacidad de una variable de modificar su contenido sin cambiar el valor en la dirección de memoria a la que apunta.

Habiendo entendido esto, podemos aterrizar estos conceptos al ecosistema de Javascript, observemos el siguiente ejemplo

```Javascript
const x = 10;
x = 5; // Uncaught TypeError: Assignment to constant variable.
```

Las variables definidas con `const` no se pueden **re-asignar**, por lo que una vez que le asignamos el valor 10, ya no hay nada más que podamos hacer para modificar ese valor. Lo mismo ocurre con objetos:

```Javascript
const x = { nombre: 'Javascript Chile' };
x.url = 'https://jschile.org/'; // Ningún problema.
x = { url: 'localhost' } ;      // Uncaught TypeError: 
                                // Assignment to constant variable.
``` 

En este caso, definimos un objeto el cual posteriormente **mutamos**, añadiéndole la propiedad `url`, sin embargo, cuando quisimos asignar un objeto diferente, nos encontramos un error. Esto es porque cuando trabajamos con objetos, lo que se almacena en la dirección de memoria que representa la variable es un **puntero**, el cual apunta a la dirección de memoria donde se almacena el objeto, y por lo tanto, intentar almacenar otro objeto implicaría cambiar el valor almacenado en la dirección de memoria de `x`, cambiando hacia donde apunta el puntero, y por lo tanto intentando **re-asignar** la variable.

Para finalizar, queda el siguiente ejemplo con `let`:

```Javascript
let x = { nombre: 'Javascript Chile' };
x.url = 'https://jschile.org/'; // Ningún problema.
x = { url: 'localhost' } ;      // Ningún problema.
``` 

Donde ambas operaciones funcionan porque `let` permite tanto la **re-asignación** como la **mutabilidad**. Dicho esto, vale la pena estudiar más sobre como la **mutabilidad** impacta en el desarrollo de nuestros productos, y en la forma en la que programamos. A modo de detalle, en este artículo utilizo el concepto **re-asignación**, porque las memorias RAM siempre tienen un dato asignado, siempre tendrán almacenado un 1 o 0 en sus celdas, por lo que sería erróneo en mi opinión hablar de **asignación** bajo el nivel de detalle en que se desenvuelve este artículo, más no significa que esté erróneo per sé hablar de **asignar** una variable.

Espero que se haya entendido bien el concepto con este artículo, y quedo atento a cualquier comentario que puedan tener, por último, quisiera mencionar que este artículo fue extraído de un **Apunte de Introducción a Javascript**, el cual redacté para mis estudiantes de Desarrollo Web, puedes descargarlo haciendo clic en la imagen:

[![Apunte Introducción a Javascript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8gc8z0we8wf2ztscnsbb.png)](https://steadycraft.notion.site/Introducci-n-a-Javascript-48a4b004556641dc8ffede99bbe071e9?pvs=25)

Nos vemos!