Залишкові параметри

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

Синтаксис

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

Опис

Перед останнім параметром функції може стояти ..., в результаті решта аргументів (наданих користувачем) будуть розміщені у  "стандартному" масиві JavaScript. Лише останній параметр може бути "залишковим".

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

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

// Виведе:
// a, один
// b, два
// manyMoreArgs, ["три", "чотири", "п'ять", "шість"]

Різниця між залишковими параметрами та об'єктом arguments

Існують три основні відмінності між залишковими параметрами та об'єктом arguments:

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

Від arguments до масиву

Залишкові параметри були запроваджені, щоб зменшити кількість шаблонного коду, спричиненого об'єктом arguments.

// До появи залишкових параметрів, "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; // цього ніколи не станеться
}

// викидає TypeError: arguments.sort is not a function
console.log(sortArguments(5, 3, 7, 1));

Щоб скористатись методами 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)
The definition of 'Function Definitions' in that specification.
Standard Початкове визначення
ECMAScript Latest Draft (ECMA-262)
The definition of 'Function Definitions' in that specification.
Draft

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
Rest parametersChrome Full support 47Edge Full support 12Firefox Full support 15IE No support NoOpera Full support 34Safari Full support 10WebView Android Full support 47Chrome Android Full support 47Firefox Android Full support 15Opera Android Full support 34Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
Full support 6.0.0
Full support 4.0.0
Disabled
Disabled From version 4.0.0: this feature is behind the --harmony runtime flag.
Destructuring rest parametersChrome Full support 49Edge No support NoFirefox Full support 52IE No support NoOpera Full support 36Safari Full support 10WebView Android Full support 49Chrome Android Full support 49Firefox Android Full support 52Opera Android Full support 36Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support Yes

Legend

Full support  
Full support
No support  
No support
User must explicitly enable this feature.
User must explicitly enable this feature.

Див. також