Actualizaciones de arrays inmutables con Array.prototype.with

Recientemente, los navegadores obtuvieron un nuevo método interoperable que puedes llamar en arrays: Array.prototype.with().

Navegadores compatibles

  • 110
  • 110
  • 115
  • 16

Origen

En este artículo, se explora cómo funciona este método y cómo usarlo para actualizar un array sin cambiar el original.

Introducción a Array.prototype.with(index, value)

El método Array.prototype.with(index, value) muestra una copia del array al que se llama con el index configurado en la nueva value que proporciones.

En el siguiente ejemplo, se muestra un array de edades. Te gustaría crear una copia nueva del array mientras cambias la segunda edad de 15 a 16:

const ages = [10, 15, 20, 25];

const newAges = ages.with(1, 16);
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 15, 20, 25] (unchanged)

Desglosar el código: ages.with(...) muestra una copia de la variable ages sin modificar el arreglo original. ages.with(1, …) reemplaza al segundo elemento (index = 1). ages.with(1, 16) asigna el segundo elemento a 16.

Así es como pudiste crear una copia nueva del array con una modificación.

Esto es bastante útil cuando quieres asegurarte de que el arreglo original permanezca intacto. En este artículo, se abordan algunos de los casos de uso relacionados. Sin embargo, por ahora, observa lo que habría pasado si hubieras utilizado la notación de corchetes:

const ages = [10, 15, 20, 25];

const newAges = ages;
newAges[1] = 16;
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 16, 20, 25] (Also changed 🙁)

Como puedes ver, en este ejemplo también se modificó la variable ages. Esto se debe a que, cuando asignas ages = newAges, JavaScript no copia el array, sino que crea una referencia al otro array. Por lo tanto, cualquier cambio en uno también afectará al otro, ya que ambos apuntan al mismo array.

Array.prototype.with() e inmutabilidad

La inmutabilidad es el centro de muchas bibliotecas y frameworks de frontend, por nombrar algunos: React (y redux) y Vue.

Además, otras bibliotecas y frameworks no necesariamente requieren inmutabilidad, pero lo fomentan para obtener un mejor rendimiento: Angular y Lit

Por lo tanto, los desarrolladores a menudo tenían que usar otros métodos que mostraban copias de los arrays, lo que sacrificaba la legibilidad del código:

const ages = [10, 15, 20, 25];

const newAges = ages.map((age, index) => {
    if (index === 1) {
         return 16;
    }
    return age;
});

console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 15, 20, 25] (Remains unchanged)

A continuación, se muestra un ejemplo de CodePen de cómo se puede usar .with() en React en combinación con useState para actualizar de manera inmutable un array de elementos:

Dado que el método .with() muestra una copia del array, puedes encadenar varias llamadas a .with() o incluso otros métodos de array. En el siguiente ejemplo, se muestra cómo aumentar las segundas y las terceras edades del array:

const ages = [10, 15, 20, 25];

const newAges = ages.with(1, ages[1] + 1).with(2, ages[2] + 1)

console.log(newAges); // [10, 16, 21, 25]
console.log(ages); // [10, 15, 20, 25] (unchanged)

Otros métodos inmutables nuevos

Otros tres métodos recientemente se volvieron interoperables:

Estos tres métodos son, según MDN, la versión en copia de sus contrapartes. Estos métodos también se pueden usar cuando se espera o se prefiere la inmutabilidad.

En conclusión, las actualizaciones inmutables se pueden realizar con mayor facilidad en JavaScript con uno de los cuatro métodos que se presentan en este artículo. Específicamente, el método .with() facilita la actualización de un solo elemento del array sin cambiar el array original.