Mises à jour de tableaux immuables avec Array.prototype.with

Les navigateurs ont récemment gagné une nouvelle méthode interopérable que vous pouvez appeler sur les tableaux : Array.prototype.with().

Browser Support

  • Chrome: 110.
  • Edge: 110.
  • Firefox: 115.
  • Safari: 16.

Source

Cet article explique comment cette méthode fonctionne et comment l'utiliser pour mettre à jour un tableau sans modifier le tableau d'origine.

Présentation de Array.prototype.with(index, value)

La méthode Array.prototype.with(index, value) renvoie une copie du tableau sur lequel elle est appelée, avec index défini sur la nouvelle value que vous fournissez.

L'exemple suivant montre un tableau d'âges. Vous souhaitez créer une copie du tableau tout en remplaçant le deuxième âge de 15 par 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)

Analyse du code : ages.with(...) renvoie une copie de la variable ages sans modifier le tableau d'origine. ages.with(1, …) remplace le deuxième élément (index = 1). ages.with(1, 16) attribue le deuxième élément à 16.

C'est ainsi que vous avez pu créer une copie du tableau avec une modification.

C'est très utile lorsque vous voulez vous assurer que le tableau d'origine reste inchangé. Cet article couvre certains des cas d'utilisation. Mais, pour l'instant, regardez ce qui se serait passé si vous aviez utilisé la notation entre crochets :

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 🙁)

Comme vous pouvez le voir, la variable ages a également été modifiée dans cet exemple. En effet, lorsque vous attribuez ages = newAges, JavaScript ne copie pas le tableau, mais crée plutôt une référence à l'autre tableau. Par conséquent, toute modification apportée à l'un affectera également l'autre, car ils pointent tous les deux vers le même tableau.

Array.prototype.with() et immuabilité

L'immuabilité est au cœur de nombreuses bibliothèques et frameworks frontend, comme React (et Redux) et Vue.

De plus, d'autres bibliothèques et frameworks ne nécessitent pas nécessairement l'immuabilité, mais l'encouragent pour de meilleures performances : Angular et Lit.

Les développeurs devaient donc souvent utiliser d'autres méthodes qui renvoyaient des copies de tableaux, ce qui sacrifiait la lisibilité du code :

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)

Voici un exemple Codepen montrant comment .with() peut être utilisé dans React en combinaison avec useState pour mettre à jour de manière immuable un tableau d'éléments :

Étant donné que la méthode .with() renvoie une copie du tableau, vous pouvez enchaîner plusieurs appels .with() ou même d'autres méthodes de tableau. L'exemple suivant montre comment incrémenter le deuxième et le troisième âge du tableau :

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)

Autres nouvelles méthodes immuables

Trois autres méthodes sont récemment devenues interopérables :

Selon MDN, ces trois méthodes sont la version de copie de leurs homologues. Ces méthodes peuvent également être utilisées lorsque l'immuabilité est attendue ou préférée.

En conclusion, les mises à jour immuables peuvent être effectuées plus facilement en JavaScript avec l'une des quatre méthodes présentées dans cet article. Plus précisément, la méthode .with() permet de mettre à jour plus facilement un seul élément du tableau sans modifier le tableau d'origine.