Recentemente, os navegadores ganharam um novo método interoperável que pode ser chamado em matrizes:
Array.prototype.with()
.
Este artigo explica como esse método funciona e como usá-lo para atualizar uma matriz sem modificar a original.
Introdução ao curso Array.prototype.with(index, value)
O método Array.prototype.with(index, value)
retorna uma cópia da matriz em que é chamada com o index
definido como o novo value
fornecido.
O exemplo abaixo mostra uma matriz de idades. Você gostaria de criar uma nova cópia da matriz enquanto altera a segunda idade de 15 para 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)
Detalhamento do código: ages.with(...)
retorna uma cópia da variável ages
sem modificar a matriz original. ages.with(1, …)
substitui o segundo item
(index = 1
). ages.with(1, 16)
atribui o segundo item a 16
.
Dessa forma, você conseguiu criar uma nova cópia da matriz com uma modificação.
Isso é muito útil quando você quer garantir que a matriz original permaneça inalterada. Este artigo aborda alguns dos casos de uso para isso. Mas, por enquanto, dê uma olhada no que teria acontecido se você tivesse usado a notação de colchete:
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 você pode notar, a variável ages
também foi modificada neste exemplo. Isso ocorre
porque, quando você atribui ages = newAges
, o JavaScript não copia a matriz, mas
cria uma referência para a outra matriz. Portanto, qualquer alteração em uma
também afeta a outra, porque ambas apontam para a mesma matriz.
Array.prototype.with() e imutabilidade
A imutabilidade está no centro de muitas bibliotecas e frameworks de front-end, entre outros: React (e redux) e Vue.
Além disso, outras bibliotecas e frameworks não exigem necessariamente imutabilidade, mas incentivam essa funcionalidade para um melhor desempenho: Angular e Lit.
Assim, muitas vezes, os desenvolvedores precisavam usar outros métodos que retornavam cópias de matrizes, o que sacrificava a legibilidade do 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)
Confira um exemplo do Codepen de como o .with()
pode ser usado no React em combinação
com useState para atualizar de forma imutável uma matriz de itens:
Como o método .with()
retorna uma cópia da matriz, você pode encadear várias
chamadas .with()
ou até mesmo outros métodos de matriz. O exemplo a seguir demonstra
como incrementar a segunda e a terceira idades a partir da matriz:
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)
Outros métodos novos imutáveis
Outros três métodos tornaram-se interoperáveis recentemente:
Array.prototype.toReversed()
, que inverte a matriz sem modificar a original.Array.prototype.toSorted()
, que classifica a matriz sem modificar a original.Array.prototype.toSpliced()
, que funciona como.splice()
, mas sem modificar a matriz original.
De acordo com o MDN, esses três métodos são a versão com cópia das equivalentes. Esses métodos também podem ser usados quando a imutabilidade é esperada ou preferida.
Em resumo, as atualizações imutáveis podem ser feitas mais facilmente em
JavaScript com um dos quatro métodos apresentados neste artigo. Especificamente,
o método .with()
facilita a atualização de um único elemento da matriz
sem modificar a matriz original.