Operador Rest no Javascript

Publicado em: 10/07/2020

O operador Rest serve para agrupar um número indeterminado de parâmetros em um elemento iterável, nesse caso, uma array, para "resumir" estes. Para melhor visualizar, como de praxe, vamos criar um exemplo. Considere o seguinte trecho:

/**
 * Função que executa um jogo de azar na taverna
 * que o nosso personagem está.
 * 
 * A dinamica é: Aposte um valor em golds (primeiro parametro)
 * nos números que você quiser, de 0 a 10 (outros parametros).
 * 
 * Você poderá apostar N números (entenda N como um numero qualquer,
 * que pode ser 1, ou 10, ou 1000).
 */
const tavernGame = (value, n1, n2, n3) => {
  let earns = 0; // Seus ganhos
  let matchNumbers = [] // Números que foram acertados
  const myNumbers = [n1, n2, n3]; // Números que você apostou
  const sortedNumbers = [3, 8, 9]; //Números sorteados

  // Iterando as duas arrays para achar os que são iguais
  sortedNumbers.forEach(num1 => {
    myNumbers.forEach(num2 => {
      if (num1 === num2) {
        matchNumbers.push(num1)
      }
    })
  })

  // Se você acertou um, então terá itens na array
  if (matchNumbers.length) {
    // Multiplica a quantia de vezes que você acertou
    // vezes o valor que você apostou
    earns = matchNumbers.length * value
    return `Você ganhou! Prêmio: ${earns} moedas de ouro!`
  }

  return 'Eita, você perdeu! Tente novamente depois!'
}

// Inicia o game
tavernGame(10, 3, 5, 8)

No exemplo acima temos um pequeno joguinho de azar que nosso personagem encontrou numa taverna aleatória. Na função que inicia o jogo declaramos no primeiro parâmetro quanto queremos apostar em golds, e depois declaramos 3 números. Na teoria deveríamos poder apostar N números, mas na prática conseguimos limitar apenas para 3, devido a limitação que tivemos ao receber esses números.

Resolvendo o problema com o operador Rest

Para solucionar o problema de não conseguir salvar de forma dinâmica N números, podemos usar o Rest, onde agruparemos tantos números quanto o usuário quiser passar na função. No nosso caso, vamos receber normalmente o parâmetro que informa o valor da aposta e então agrupar todos os números a seguir numa array. Veja o nosso programa refatorado se utilizando do operador Rest:

/**
 * Função que executa um jogo de azar na taverna
 * que o nosso personagem está.
 * 
 * A dinamica é: Aposte um valor em golds (primeiro parametro)
 * nos números que você quiser, de 0 a 10 (outros parametros).
 * 
 * Você poderá apostar N números (entenda N como um numero qualquer,
 * que pode ser 1, ou 10, ou 1000).
 */
- const tavernGame = (value, n1, n2, n3) => {
+ const tavernGame = (value, ...myNumbers) => { // agrupado todos os numeros aqui
  let earns = 0; // Seus ganhos
  let matchNumbers = [] // Números que foram acertados
- const myNumbers = [n1, n2, n3]; // myNumbers agora é nosso parametro rest
  const sortedNumbers = [3, 8, 9]; //Números sorteados
  // Iterando as duas arrays para achar os que são iguais
  sortedNumbers.forEach(num1 => {
    myNumbers.forEach(num2 => {
      if (num1 === num2) {
        matchNumbers.push(num1)
      }
    })
  })
  // Se você acertou um, então terá itens na array
  if (matchNumbers.length) {
    // Multiplica a quantia de vezes que você acertou
    // vezes o valor que você apostou
    earns = matchNumbers.length * value
    return `Você ganhou! Prêmio: ${earns} moedas de ouro!`
  }
  return 'Eita, você perdeu! Tente novamente depois!'
}
// Inicia o game
tavernGame(10, 3, 5, 8)

Com apenas duas pequenas modificações tornamos nossa função extremamente flexível, onde agora ela poderá receber, vamos la, 1000 parâmetros, e todos esses, com exceção do valor apostado, ficara na array gerada pelo operador Rest!

Consideraçoes finais

Essa sintaxe pode ser um pouco chata de pegar de início, devido ao fato que esse operador tem dois comportamentos: Rest e Spread (leia mais sobre o Spread aqui: Operador Spread no Javascript), mas com um pouco de leitura e prática logo dominamos o assunto e nos tornamos desenvolvedores melhores que escrevem código cada vez melhor. Ate o próximo post!