Opa, tudo bem? Tentarei te ajudar um pouco com o maravilhoso operador do JavaScript.

O operador spread (...) é muito utilizado quando usamos os conceitos de programação funcional, pois nessa abordagem, não mudamos o dado original, mas fazemos uma cópia e daí é com ela que nós brincamos.

Em resumo, o operador spread serve:

  • Copiar o conteúdo de um array
  • Mesclar o conteúdo de arrays em um só
  • Copiar o conteúdo de um objeto
  • Ser passado como argumento de uma função

Copiando o conteúdo de um array

Vamos começar. Como sabemos (ou não), no javascript objetos são passados por referência, ou seja, quando fazemos isso:

let arr1 = [1,2,3,4]
let arr2 = arr1

não estamos copiando o array e sim passando a referencia (o endereço de memória), assim, se mudarmos o valor de arr2, também mudamos o valor de arr1.

arr2.push(5)
console.log(arr1)  //=> [1,2,3,4,5] 
console.log(arr2)  //=> [1,2,3,4,5]

Dito isso, precisamos de uma maneira para copiar objetos no JavaScript, é aí que o spread entra.

No mesmo cenário acima, queremos copiar o array original e fazer operações com a cópia:

let arr1 = [1,2,3,4]
let arr2 = [...arr1]

Agora o array arr2 é uma cópia (ou seja, arr2 aponta para um endereço de memória diferente de arr1) e tudo o que fizermos com ele não alterará o arr1. (simples assim!)

arr2.push(5)
console.log(arr1)  //=> [1,2,3,4] 
console.log(arr2)  //=> [1,2,3,4,5]

Mesclando dois ou mais arrays

O spread pode ser usado para mesclar dois ou mais arrays em apenas uma variável.

let cidadesDoBrasil = ['Rio de Janeiro', 'São Paulo', 'Santos']
let cidadesDaArgentina = ['Buenos Aires', 'Bariloche', 'Córdova']

let cidadesdaAmerica = [...cidadesDoBrasil, ...cidadesDaArgentina]

No exemplo mostrado mesclamos dois arrays em um, mas podemos fazer o mesmo procedimento para quantos arrays quisermos.

Extra 1: Recuperando um valor de um array

Antes de partimos para usarmos o spread em objetos, gostaria de mostrar mais uma coisa.

Podemos usar o spread para obter o último valor de um array sem alterar o valor original

let cidadesDoBrasil = ['Rio de Janeiro', 'São Paulo', 'Santos']
let [ultimo] = [...cidadesDoBrasil].reverse()
console.log(ultimo)   // => Santos

No exemplo acima, copiamos o valor do array original e aplicamos o método .reverse(), tal método altera o valor original do array, por isso aplicamos na cópia e então usamos desestruturação (Veja mais) para obter o valor na primeira posição do array.

Extra 2: Removendo um elemento em uma posição qualquer do array

Podemos utilizar o spread para nos ajudar a remover um elemento em uma posição qualquer do array. Digamos que tenhamos o seguinte array:

let arr1 = [1,2,3,4,5,6,7,8];

E desejamos remover o elemento com valor igual a 4. Suponha também que não sabemos a posição dele. Podemos resolver o problema da seguinte forma:

let arr1 = [1,2,3,4,5,6,7,8];
const index = arr1.findIndex(el => el === 4);

arr1 = [
  ...arr1.slice(0, index),
  ...arr1.slice(index+1)
];

console.log(arr1) //=> [1,2,3,5,6,7,8]

Copiando o conteúdo de um objeto

Similar com arrays, podemos usar o spread para copiar o conteúdo de um JSON. O procedimento é o mesmo já falado:

const pessoa ={
    nome: 'John',
    sobrenome: 'Doe',
    age: 26,
    senha: 'password'
}

const copiaPessoa = { ...pessoa }

A constante copiaPessoa possui os mesmos dados de pessoa porém salvos em um endereço de memória diferente, ou seja, podemos alterá-la sem medo de mudar o original.

Extra 3: Copiando o conteúdo de um objeto e alterando um valor

No processo de cópia, queremos apagar a informação de senha, pois iremos printar na tela as informaçoes da pessoa e não queremos que vejam a senha da pessoa.

const pessoa ={
    nome: 'John',
    sobrenome: 'Doe',
    age: 26,
    senha: 'password'
}

const copiaPessoa = { ...pessoa, password: 'new pass' }

Desse jeito, copiamos as informações da pessoa e sobrescremos o campo senha. Com isso podemos printar na tela a variável copiaPessoa, mas se por acaso desejamos verificar a senha da pessoa, para autenticá-la, ainda temos a informação original e podemos fazer isso.

Obs: da mesma forma que podemos alterar um valor, podemos adicionar um novo valor. No código acima, caso o campo password não existisse em pessoa, ele passaria a existir em copiaPessoa.

Spread como argumento de uma função

Podemos imaginar um cenário que temos uma função que recebe uma quantidade desconhecida de parametros, nesse cenário podemos utilizar o spread para nos ajudar.

function caminho(...locais) {
  let [inicio, ...restante] = locais;
  let [fim, ...resto] = restante.reverse();

console.log(
`O cara começou em ${inicio} e terminou em ${fim}. Durante o processo ele passou por outros ${resto.length} locais`
);
}

caminho("São Paulo", "Santos", "São José dos Campos", "Rio de Janeiro", "Belo Horizonte");

Na função acima, podemos passar qualquer quantidade de argumentos, nela usamos ainda ajuda de desestruturação (Veja mais).

#Fim