¿Por qué la inmutabilidad es tan importante en JavaScript?
¿Qué tiene de malo la mutabilidad o la mutación de los objetos en el código?
¿No simplifica las cosas?
Antes de profundizar en la comprensión de la importancia de la inmutabilidad, primero debemos comprender el concepto de mutabilidad e inmutabilidad en el desarrollo de software.
Una princesa besa a una rana con la esperanza de que se convierta en un apuesto príncipe. El concepto de inmutabilidad dice que una rana siempre será una rana. El concepto de inmutabilidad se origina principalmente a partir de la programación funcional y orientada a objetos. Siempre que queramos realizar cambios en algunos datos (por ejemplo, en un objeto o una array), debemos recuperar un nuevo objeto con los datos actualizados en lugar de modificar directamente el original.
Piense en la inmutabilidad como «guardar como» porque sabe que devuelve un objeto recién cambiado, mientras que la mutación tradicional en el lugar sería como «guardar» significa actualizar el original y dejar un estado anterior. La estructura de los datos inmutables no se puede cambiar.
Los datos serían los originales y una vez creado el objeto no podemos modificar su estado en un objeto inmutable. Considere el concepto de inmutabilidad como el cuerpo humano que no se ve afectado por el mundo exterior. Un estado con tranquilidad.
El concepto de mutación es viceversa. La mutabilidad describe si el estado de un objeto se puede modificar después de su declaración o no. Considérelo como si besar a una rana da como resultado la transformación de un príncipe. Tomemos un ejemplo en el que tenemos una variable y le asignamos un valor. Más tarde, si necesitamos modificar el valor de esta variable, y la cambiamos y luego cambiamos su estado, el objeto se considera mutable .
Los desarrolladores que nunca trabajaron con el concepto de inmutabilidad pueden confundirse con la asignación de una variable a un nuevo valor o reasignación. En JavaScript, String y Numbers son tipos de datos inmutables.
JavaScript no es un buen lenguaje para trabajar con datos de forma inmutable. En JavaScript, las arrays y los objetos no son inmutables. Sus valores se pueden cambiar con el tiempo. Ambos siempre se pasan como referencia y la gran mayoría de los métodos disponibles mutan los datos en su lugar. Puedes considerar el ejemplo dado a continuación…
Ejemplo: Ordenar método de array
Javascript
const a = [2, 1, 4, 3]; console.log(a); const b= a.sort(); console.log(b); console.log(a)
Output: [2, 1, 4, 3] [1, 2, 3, 4] [1, 2, 3, 4]
Hemos asignado una array a la variable «a» y estamos realizando la operación de clasificación en ella. La array ordenada se asigna a la variable «b» y puede ver que estamos obteniendo la array ordenada para ambas variables después de realizar la operación de clasificación. Aquí, los objetos y las arrays se pasan como referencia en lugar de copiar ambas variables, «a» y «b», que apuntan a la misma array en la memoria y esa array fue mutada directamente por el método sort.
Muchos métodos de array son el método Mutator. copyWithin, fill, pop, push, reverse, shift, sort, splice, unshift todos estos métodos permiten la mutabilidad. slice, from, map y filter son inmutables porque crea una nueva array sin mutar la array original. Los métodos de objeto que son inmutables son object.assign.
Para hacer que los objetos y las arrays sean inmutables, puede usar algunas técnicas en JavaScript y crear nuevos valores sin modificar el contenido original. No cambie el valor original de un objeto directamente. Trate este objeto como inmutable y devuelva un objeto completamente nuevo con el valor actualizado.
El operador de propagación es útil para mutar la array y los objetos porque itera sobre los valores y permite copiar las propiedades de los valores existentes en el nuevo valor.
Entendamos este concepto con un ejemplo más. Tenemos una array de datos que contiene la cantidad de días que un empleado trabajó en algún proyecto.
Ejemplo: método de array de división y ordenación
Javascript
var daysWorked = [7, 7, 5, 9, 8, 6, 6, 7, 9, 5]; console.log(daysWorked); //slice for 6 days work var lastSixMonths = daysWorked.slice(0,6); console.log(daysWorked) console.log(lastSixMonths); // let's sort the days worked //mutable object var sortedDaysWorked = daysWorked.sort(); console.log(sortedDaysWorked); console.log(daysWorked) //slice for seven days work var lastSevenMonths = daysWorked.slice(0,7); console.log(lastSevenMonths); console.log(daysWorked)
[ 7, 7, 5, 9, 8, 6, 6, 7, 9, 5] [ 7, 7, 5, 9, 8, 6, 6, 7, 9, 5 ] [ 7, 7, 5, 9, 8, 6 ] [ 5, 5, 6, 6, 7, 7, 7, 8, 9, 9 ] [ 5, 5, 6, 6, 7, 7, 7, 8, 9, 9] [ 5, 5, 6, 6, 7, 7, 7 ] [ 5, 5, 6, 6, 7, 7, 7, 8, 9, 9]
En el método anterior, hemos utilizado dos métodos en la variable daysWorked.
- Slice: en el ejemplo anterior, estamos logrando la inmutabilidad utilizando el método de división. Este método divide el objeto original y, en lugar de modificar el conjunto de datos original, obtenemos la nueva copia del objeto lastSixMonths.
- Ordenar: este método es mutable y está ordenando el conjunto de datos original. Este método nos impide hacer más cálculos en el conjunto de datos.
Ejemplo: asignar método de objeto
Javascript
const GFG = { article:"javascript", date:"30/05/2022" } const gfg1=GFG gfg1.article="react"; console.log(gfg1); console.log(GFG); gfg2=Object.assign({},gfg1); gfg2.article="typescript"; console.log(gfg2); console.log(gfg1); console.log(GFG);
Output: { article: 'react', date: '30/05/2022' } { article: 'react', date: '30/05/2022' } { article: 'typescript', date: '30/05/2022' } { article: 'react', date: '30/05/2022' } { article: 'react', date: '30/05/2022' }
Object.assign es un método que toma un argumento, un objeto vacío y un objeto de origen (el objeto que debe copiarse). así que aquí las propiedades del objeto gfg1 se copiaron en el argumento de objeto vacío de gfg2 sin mutar el objeto gfg1.
Ejemplo: operador de propagación
Javascript
const GFG = { article:"javascript", date:"30/05/2022" } const gfg1=GFG gfg1.article="react"; console.log(gfg1); console.log(GFG); //spread operator create new reference gfg2= {...gfg1} gfg2.article="typescript"; console.log(gfg2); console.log(gfg1); console.log(GFG);
Output: { article: 'react', date: '30/05/2022' } { article: 'react', date: '30/05/2022' } { article: 'typescript', date: '30/05/2022' } { article: 'react', date: '30/05/2022' } { article: 'react', date: '30/05/2022
Importancia de la inmutabilidad en JavaScript
¿Cuál es la parte buena de la inmutabilidad? ¿Por qué debemos preocuparnos por la inmutabilidad en primer lugar? ¿Por qué siquiera molestarse?
La inmutabilidad brinda un control más estricto sobre sus datos de inmediato, lo que hace que su código sea más seguro y predecible. En otras palabras, los objetos inmutables le permiten controlar la interfaz y el flujo de datos de manera predecible, descubriendo los cambios de manera eficiente. También facilita la implementación de funciones complejas como deshacer/rehacer, depuración de viajes en el tiempo, actualizaciones y reversiones optimistas, etc.
Si hablamos de la biblioteca frontend React, la biblioteca de administración de estado de Vue os Redux, la inmutabilidad también puede ayudar a lograr un mejor rendimiento al permitir comparaciones rápidas y económicas entre las versiones del estado antes y después de los cambios. Los componentes pueden aprovechar esto y volver a renderizarse de manera inteligente solo cuando sea necesario. Esto puede aumentar significativamente el rendimiento.
Los principales beneficios de la inmutabilidad son la previsibilidad, el rendimiento y un mejor seguimiento de mutaciones.
1. Previsibilidad
En cualquier aplicación, cuando trabajamos en algunas bibliotecas front-end, declaramos muchos estados en ellas. Realizamos la acción asíncrona y actualiza el estado original (mutación). Una vez que el usuario final comience a usarlo, el estado actualizado será significativamente diferente del estado inicial. Mutar el estado oculta los cambios y crea efectos secundarios que pueden causar varios errores. La depuración se vuelve difícil en tales casos.
Cuando mantiene la arquitectura de su aplicación inmutable y el modelo mental simple, se vuelve más fácil predecir el estado de los datos en un momento dado y luego puede estar seguro de que no creará efectos secundarios desagradables.
2. Rendimiento
Crear una memoria de costo de objeto inmutable. ¿Cómo? Cuando agrega valor a un objeto inmutable, necesita crear un nuevo objeto y en este nuevo objeto, copia el valor existente con el nuevo valor que requiere memoria adicional. Para reducir el consumo de memoria utilizamos el uso compartido estructural.
Cualquier actualización que hagamos devuelve nuevos valores, pero compartimos las estructuras internamente para reducir el consumo de memoria. Por ejemplo, si agrega a un vector con 100 elementos, no crea un nuevo vector de 101 elementos de largo. Solo unos pocos objetos pequeños se asignan internamente.
3. Seguimiento de mutaciones
Una de las ventajas de la inmutabilidad es que puede optimizar su aplicación haciendo uso de la igualdad de referencia y valor. Esto hace que sea fácil identificar si algo ha cambiado. Puede considerar el ejemplo de cambio de estado en el componente React. shouldComponentUpdate se puede usar para verificar si el estado es idéntico comparando el objeto de estado y evitando que se represente innecesariamente.
La inmutabilidad le permite realizar un seguimiento de los cambios que se producen en estos objetos como una string de eventos. Las variables tienen nuevas referencias que son fáciles de rastrear en comparación con las variables existentes. Esto ayuda a depurar el código y construir la aplicación concurrente. Además, los depuradores de eventos lo ayudan a reproducir eventos DOM con reproducciones de video que funcionan en el seguimiento de mutaciones.
Por primera vez, el concepto de inmutabilidad puede resultarle confuso. Puede hacerlo mejor si comprende la necesidad y los beneficios de la inmutabilidad. Cuando el estado está mutado, te topas con muchos errores y lidiar con eso te hace entender mucho mejor el concepto de inmutabilidad.
Publicación traducida automáticamente
Artículo escrito por anuupadhyay y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA