Os operadores rest e spread permitem trabalhar com múltiplos parâmetro em funções. Sendo o Rest utilizado para permitir que uma função receba um número indefinido de parâmetros, enquanto o spread permite definir um número indefinido de parâmetros para uma função, Array ou objeto.


Guia do artigo:

Visão geral

É comum a necessidade de passar um número indefinido de parâmetros para uma função, Array ou Objetos, nesses casos podemos utilizar os operadores rest e spread como podemos ver nos exemplos a seguir, sendo o primeiro exemplo o rest:

function listagem (primeiro, segundo, ...outros) {
    console.log(`Na lista estão: $, $. Os demais são: ${outros.join(', ')}.`)
  }
  
  listagem('Pedro', 'Maria', 'João', 'Marcus', 'Tiago')
  // Na lista estão: Pedro, Maria. Os demais são: João, Marcus, Tiago.

Abaixo um exemplo de uso do spread concatenando dois Arrays sem precisar do uso do método concat:

const pessoas = ['Pedro', 'Maria', 'João']
  
  const todasAsPessoas = [ ...pessoas, 'Marcus', 'Tiago']
  
  console.log(todasAsPessoas)
  // [ 'Pedro', 'Maria', 'João', 'Marcus', 'Tiago' ]

Rest

Permite representar um número indefinido de argumentos na forma de um Array.

Sintaxe

(argA, argB, ...outrosArgs) => void

Na prática

Exemplo 1

No exemplo abaixo veremos como o operador rest permite capturar os argumentos de uma função de forma simples:

function soma (...valores) {
    var total = 0
  
    for (const item of valores) {
      total += parseInt(item, 10)
    }
  
    return total
  }
  
  console.log(soma(1, 2, 3, 4, 50, 10, 23))
  // 93

O uso das reticencias indica que todos os valores passados por parâmetros serão passados para a função como a variável valores que contem um Array de valores.

Exemplo 2

No exemplo abaixo veremos como o operador rest permite capturar os argumentos de uma função de maneira simples:

function getArgumentos (valor1, ...outrosValores) {
    return {
      valor1,
      outrosValores
    }
  }
  
  console.log(getArgumentos('DevMedia', 'curte', 'Javascript'))
  // { valor1: 'DevMedia', outrosValores: [ 'curte', 'Javascript' ] }
Exemplo 3

Considere que temos uma lista de produtos e seja necessário efetuar a soma de todos os itens passados como argumento da função.

const produtos = [
    { descricao: 'Papel Ofício', quantidade: 10, valor: 10.50 },
    { descricao: 'Lapis preto', quantidade: 20, valor: 0.50 }
  ]
  
  function total (...produtos) {
    return produtos
      .map(produto => produto.quantidade * produto.valor)
      .reduce((a, b) => a + b, 0)
  }
  
  console.log(total(...produtos))

Perceba que o map foi utilizado para percorrer os itens do Array de produtos convertendo cada item em um numero a partir da soma da quantidade e valor dos produtos.

Spread

Permite expandir uma expressão em um local que receba múltiplos argumentos ou elementos.

Sintaxe

[{(...argumentos)}]

Na prática

Exemplo 1: Spread em chamadas de função

Considere dois valores que precisam ser somados por uma função simples: utilizando o operador spread podemos fazer esta tarefa sem que seja necessário atribuir os valores deste Array a uma variável. No exemplo abaixo podemos ver melhor como este processo pode ser feito:

const soma = (a, b) => a + b
  
  const valores = [ 10, 50 ]
  
  console.log(soma(...valores)) // saída: 60
Exemplo 2

Podemos utilizar o operador spread para concatenar dois Arrays como no exemplo abaixo:

const primeirosItens = [ 1, 2 , 3 ]
  
  const outrosItens = [ ...primeirosItens, 4, 5, 6 ]
  
  console.log(outrosItens) // [ 1, 2 , 3, 4, 5, 6 ]
Exemplo 3

No exemplo abaixo utilizamos o operador spread para recuperar um número de argumentos indefinidos e defini-los ao valorB ao utilizar reticências antecedendo o nome do argumento:

function logger (valorA, ...valorB) {
    console.log(valorA, valorB)
  }
  
  logger('DevMedia', 'S2', 'Javascript')
  // 'DevMedia', [ 'S2', 'Javascript' ]
Exemplo 4: Spread em uma função

No exemplo abaixo utilizamos o spread em uma função que efetua a soma de todos os argumentos que receber.

function soma () {
    return Object.values(arguments).reduce((a, b) => a + b, 0)
  }
  
  const itens = [ 1, 3, 6, 8 ]
  
  console.log(soma(...itens)) // 18

Perceba na linha 11 que o Array e passado como parâmetro sendo precedido por uma reticencias, isso significa que seus valores serão alocados em cada argumento da função.

Compatibilidade

Engine Versão Minima
Node.JS ( V8) 6.4.0
Safari ( WebKit) 11.1
Chrome ( V8) 68
Microsoft Edge ( ChakraCore) 17
Firefox ( Gecko) 61

Nota: O Opera utiliza atualmente grande parte do código do Chrome como base para o seu próprio desenvolvimento e por isso ele não é mencionado nesta listagem.

Confira também