Rest parameters в JavaScript

Rest parameters или остаточные параметры позволяют собрать несколько аргументов функции в один массив.

function showSkills(...skills) {
  console.log(skills);
}

showSkills('HTML', 'CSS', 'JavaScript');

Результат:

['HTML', 'CSS', 'JavaScript']

Все переданные значения попали в параметр skills. Внутри функции это обычный массив.

Что такое rest parameters

Иногда функция должна принимать неизвестное количество аргументов.

Например, мы хотим написать функцию, которая складывает любое количество чисел.

function sum(...numbers) {
  let result = 0;

  for (let number of numbers) {
    result += number;
  }

  return result;
}

console.log(sum(2, 4, 6));
console.log(sum(10, 20, 30, 40));

Результат:

12
100

Параметр numbers собирает все аргументы в массив. Поэтому по нему можно пройтись циклом for…of.

Синтаксис

Rest parameter записывается через три точки перед именем параметра.

function functionName(...items) {
  console.log(items);
}

Три точки говорят JavaScript: собери оставшиеся аргументы в массив items.

Название параметра может быть любым.

function logValues(...values) {
  console.log(values);
}

Несколько аргументов

Главная польза rest parameters в том, что функция может принять столько аргументов, сколько ей передали.

function getAverage(...numbers) {
  let sum = 0;

  for (let number of numbers) {
    sum += number;
  }

  return sum / numbers.length;
}

console.log(getAverage(10, 20));
console.log(getAverage(10, 20, 30, 40));

Результат:

15
25

Если аргументов стало больше, функцию не нужно переписывать.

Обычные параметры вместе с rest

Rest parameters можно использовать вместе с обычными параметрами.

function showUser(name, ...skills) {
  console.log(name);
  console.log(skills);
}

showUser('Анна', 'HTML', 'CSS', 'JavaScript');

Результат:

Анна
['HTML', 'CSS', 'JavaScript']

Первый аргумент попал в параметр name. Все остальные аргументы собрались в массив skills.

Rest parameter должен быть последним

Остаточный параметр всегда ставится последним в списке параметров.

function showUser(name, age, ...skills) {
  console.log(name);
  console.log(age);
  console.log(skills);
}

Так JavaScript понимает, какие значения нужно положить в обычные параметры, а какие собрать в массив.

Так писать нельзя:

function showUser(...skills, name) {
  console.log(name);
}

После rest parameter не может быть других параметров.

Отличие от arguments

arguments тоже хранит переданные аргументы, но это не настоящий массив.

Rest parameter сразу создает массив. Поэтому с ним можно использовать методы массивов.

function doubleNumbers(...numbers) {
  return numbers.map(function (number) {
    return number * 2;
  });
}

console.log(doubleNumbers(1, 2, 3));

Результат:

[2, 4, 6]

В новом коде rest parameters обычно удобнее и понятнее, чем arguments.

Rest parameters и стрелочные функции

Rest parameters работают и в стрелочных функциях.

const sum = (...numbers) => {
  return numbers.reduce(function (result, number) {
    return result + number;
  }, 0);
};

console.log(sum(5, 10, 15));

Результат:

30

Это особенно полезно, потому что у стрелочных функций нет своего arguments.

Итого

1. Rest parameters собирают несколько аргументов функции в массив.

2. Запись выглядит так: …numbers, …items, …values.

3. Rest parameter должен быть последним в списке параметров.

4. В отличие от arguments, rest parameter сразу является массивом.

5. Rest parameters работают в обычных и стрелочных функциях.