Оставшиеся параметры (rest parameters)

 

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

Синтаксис

function(a, b, ...theArgs) {
  // ...
}

Описание

Если последний именованный аргумент функции имеет префикс ..., он автоматически становится массивом с элементами от 0 до theArgs.length в соответствии с актуальным количеством аргументов, переданных в функцию.

function myFun(a, b, ...manyMoreArgs) {
  console.log("a", a); 
  console.log("b", b);
  console.log("manyMoreArgs", manyMoreArgs); 
}

myFun("один", "два", "три", "четыре", "пять", "шесть");

// Console Output:
// a, один
// b, два
// manyMoreArgs, [три, четыре, пять, шесть]

Отличия оставшихся параметров от объекта arguments

Существует три основных отличия оставшихся параметров от объекта arguments:

  • оставшиеся параметры включают только те, которым не задано отдельное имя, в то время как объект arguments содержит все аргументы, передаваемые в функцию;
  • объект arguments не является массивом, в то время как оставшиеся параметры являются экземпляром Array и методы sort, map, forEach или pop могут непосредственно у них использоваться;
  • объект arguments имеет дополнительную функциональность, специфичную только для него (например, свойство callee).

Из аргументов в массив

Оставшиеся параметры были введены для уменьшения количества шаблонного кода:

// До появления оставшихся параметров "arguments" конвертировали в обычный массив используя:

function f(a, b) {

  var normalArray = Array.prototype.slice.call(arguments);
  // -- или --
  var normalArray = [].slice.call(arguments);
  // -- или --
  var normalArray = Array.from(arguments);

  var first = normalArray.shift(); // OK, даёт первый аргумент
  var first = arguments.shift(); // ERROR (arguments не является обычным массивом)

}

// Теперь мы можем легко получить оставшиеся параметры как обычный массив

function f(...args) {
  var normalArray = args;
  var first = normalArray.shift(); // OK, даёт первый аргумент
}

Деструктуризация оставшихся параметров

Оставшиеся парамерты могут быть деструктуризованы (только массивы). Это означает, что их данные могут быть заданы как отдельные значения. Смотрите Деструктурирующее присваивание.

function f(...[a, b, c]) {
  return a + b + c;
}

f(1)          // NaN (b и c равны undefined)
f(1, 2, 3)    // 6
f(1, 2, 3, 4) // 6 (четвёртый параметр не деструктурирован)

Примеры

В этом примере первый аргумент задан как "a", второй как "b", так что эти аргументы используются как обычно. Однако третий аргумент "manyMoreArgs" будет массивом, который содержит 3-й, 4-й, 5-й, 6-й ... n-й аргументы, которые передаст пользователь.

function myFun(a, b, ...manyMoreArgs) {
  console.log("a", a); 
  console.log("b", b);
  console.log("manyMoreArgs", manyMoreArgs); 
}

myFun("один", "два", "три", "четыре", "пять", "шесть");

// a, один
// b, два
// manyMoreArgs, [три, четыре, пять, шесть]

Ниже... даже если передано одно значение последним аргументом, оно всё равно помещается в массив.

// использование той же функции, что и в примере выше

myFun("один", "два", "три");

// a, один
// b, два
// manyMoreArgs, [три]

Ниже... третий аргумент не был передан, но "manyMoreArgs" всё ещё массив (хотя и пустой).

// использование той же функции, что и в примере выше

myFun("один", "два");

// a, один
// b, два
// manyMoreArgs, []

Поскольку theArgs является массивом, количество элементов в нём определяется свойством length:

function fun1(...theArgs) {
  console.log(theArgs.length);
}

fun1();  // 0
fun1(5); // 1
fun1(5, 6, 7); // 3

В следующем примере, оставшиеся параметры используются для сбора всех аргументов после первого в массив. Каждый из них умножается на первый параметр и возвращается массив:

function multiply(multiplier, ...theArgs) {
  return theArgs.map(function(element) {
    return multiplier * element;
  });
}

var arr = multiply(2, 1, 2, 3); 
console.log(arr); // [2, 4, 6]

Методы Array могут быть использованы на оставшихся параметрах, но не на объекте arguments

function sortRestArgs(...theArgs) {
  var sortedArgs = theArgs.sort();
  return sortedArgs;
}

console.log(sortRestArgs(5, 3, 7, 1)); // 1, 3, 5, 7

function sortArguments() {
  var sortedArgs = arguments.sort(); 
  return sortedArgs; // это никогда не выполнится
}


console.log(sortArguments(5, 3, 7, 1)); // TypeError (arguments.sort is not a function)

Чтобы использовать методы Array на объекте arguments, нужно преобразовать его в настоящий массив.

function sortArguments() {
  var args = Array.from(arguments);
  var sortedArgs = args.sort();
  return sortedArgs;
}
console.log(sortArguments(5, 3, 7, 1)); // 1, 3, 5, 7

Спецификации

Спецификация Статус Комментарий
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'Определение функций' в этой спецификации.
Стандарт Изначальное определение.
ECMAScript Latest Draft (ECMA-262)
Определение 'Function Definitions' в этой спецификации.
Черновик

Совместимость с браузерами

Update compatibility data on GitHub
КомпьютерыМобильныеServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome для AndroidFirefox для AndroidOpera для AndroidSafari on iOSSamsung InternetNode.js
Rest parametersChrome Полная поддержка 47Edge Полная поддержка 12Firefox Полная поддержка 15IE Нет поддержки НетOpera Полная поддержка 34Safari Полная поддержка 10WebView Android Полная поддержка 47Chrome Android Полная поддержка 47Firefox Android Полная поддержка 15Opera Android Полная поддержка 34Safari iOS Полная поддержка 10Samsung Internet Android Полная поддержка 5.0nodejs Полная поддержка 6.0.0
Полная поддержка 6.0.0
Полная поддержка 4.0.0
Отключено
Отключено From version 4.0.0: this feature is behind the --harmony runtime flag.
Destructuring rest parametersChrome Полная поддержка 49Edge Нет поддержки НетFirefox Полная поддержка 52IE Нет поддержки НетOpera Полная поддержка 36Safari ? WebView Android Полная поддержка 49Chrome Android Полная поддержка 49Firefox Android Полная поддержка 52Opera Android Полная поддержка 36Safari iOS ? Samsung Internet Android Полная поддержка 5.0nodejs Полная поддержка Да

Легенда

Полная поддержка  
Полная поддержка
Нет поддержки  
Нет поддержки
Совместимость неизвестна  
Совместимость неизвестна
Пользователь должен сам включить эту возможность.
Пользователь должен сам включить эту возможность.

Смотрите также