残余引数

残余引数構文により、不定数の引数を配列として表すことができます。

構文

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

解説

関数の最後の引数に ... の接頭辞を付けると、(ユーザーが提供した) その位置にある残りの引数を JavaScript の「標準の」配列の中に入れることができます。

最後の引数のみが「残余引数」になることができます。

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

myFun("one", "two", "three", "four", "five", "six")

// コンソール出力:
// a, one
// b, two
// manyMoreArgs, [three, four, five, six]

残余引数と arguments オブジェクトとの違い

残余引数と arguments オブジェクトの間には、主に 3 つの違いがあります。

  • 残余引数は、各引数に個別の名前が与えられていないだけ (すなわち、正式に定義された関数式) であるのに対し、arguments オブジェクトは、関数に渡されるすべての引数を含みます。
  • arguments オブジェクトは実配列ではありません。一方、残余引数は Array インスタンスです。これは、sort, map, forEach, pop などのメソッドを直接適用できることを意味します。
  • arguments オブジェクトは、(callee プロパティのように) 自身への固有の追加機能を持っています。

arguments から配列へ

残余引数は、引数により引き起こされる定型コードを減らすために導入されました。

// 残余引数の登場以前は、"arguments" を普通の配列に変換するには以下のようにしていました。

function f(a, b) {

  let normalArray = Array.prototype.slice.call(arguments)
  // -- or --
  let normalArray = [].slice.call(arguments)
  // -- or --
  let normalArray = Array.from(arguments)

  let first = normalArray.shift()  // OK、最初の引数が得られる
  let first = arguments.shift()    // エラー (arguments は通常の配列ではない)
}

// 残余引数を使ってふつうの配列へのアクセスが得られるようになりました

function f(...args) {
  let normalArray = args
  let first = normalArray.shift() // OK、最初の引数が得られる
}

残余引数の使用

この例では、最初の引数が a に、2番目の引数が b に割り当てられますので、これらの名前付き引数はふつう通り使われます。

しかし、3番目の引数、manyMoreArgs は、3番目、4番目、5番目、6番目、・・・n番目 — ユーザーが入れただけの数の引数を持つ配列になります。

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

myFun("one", "two", "three", "four", "five", "six")

// a, one
// b, two
// manyMoreArgs, [three, four, five, six]

以下の例では・・・値が 1 つしかなくても、最後の引数は配列に入れられます。

// 上記の例と同じ関数定義を使用

myFun("one", "two", "three")

// a, one
// b, two
// manyMoreArgs, [three]

以下の例では、3番目の引数が提供されていませんが、manyMoreArgs は配列のままです (ただし空のものです)。

// 上記の例と同じ関数定義を使用

myFun("one", "two")

// a, one
// b, two
// manyMoreArgs, []

引数の長さ

theArgs は配列なので、length プロパティを使用して要素数を取得することができます。

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

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

通常の引数と残余引数

次の例では、残余引数を使用して 2 番目の引数から最後の引数までを配列に集めています。それからそれぞれを最初の引数と乗算し、その配列を返します。

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

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

arguments との使用

Array のメソッドを残余引数で利用することができますが、arguments オブジェクトでは利用できません。

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

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

function sortArguments() {
  let sortedArgs = arguments.sort()
  return sortedArgs  // これは実行されない
}


console.log(sortArguments(5, 3, 7, 1))  
// TypeError が発生 (arguments.sort は関数ではない)

arguments オブジェクト上で Array メソッドを使用するには、まずオブジェクトを実配列に変換する必要があります。

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

仕様

仕様書
ECMAScript (ECMA-262)
Function Definitions の定義

ブラウザーの互換性

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung 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 完全対応 79Firefox 完全対応 52IE 未対応 なしOpera 完全対応 36Safari 完全対応 10WebView Android 完全対応 49Chrome Android 完全対応 49Firefox Android 完全対応 52Opera Android 完全対応 36Safari iOS 完全対応 10Samsung Internet Android 完全対応 5.0nodejs 完全対応 あり

凡例

完全対応  
完全対応
未対応  
未対応
ユーザーが明示的にこの機能を有効にしなければなりません。
ユーザーが明示的にこの機能を有効にしなければなりません。

関連情報