JS.next

JavaScriptの最新実装情報を追うブログ

Restパラメータ/Spreadコールが実装されてきている

概要

Restパラメータ/Spreadコールを使うと、可変長引数が扱いやすくなる。


Restパラメータ [4.2.71] [4.5.48]

関数定義の引数部分に『...args』と記述すると、全ての引数の配列をargsで受け取ることができる。 [4.2.71]
例:引数の中で最大の数を得る

max( 5, 15, 10 )

function max( ...args ) {
  console.log( Array.isArray( args ) )  //-> true
  console.log( args.length )               //-> 3
  var max = args.reduce( (max, n) => n > max ? n : max, -Infinity  )
  console.log( max )                         //-> 15
}


また、argumentsのないアロー関数でも使用することができる。 [4.5.48]
例:

var max = (...args) => args.reduce( (max, n) => n > max ? n : max, -Infinity  )
console.log( max( 5, 15, 10 ) )  //-> 15


そして、Restパラメータの前に通常の引数を記述することによって、残りの引数を配列として得ることができる。 [4.2.71]
例:複数のメッセージを一定間隔ごとに表示する

function setMessageInterval( interval, ...messages ) {
  var tid = setInterval( () => {
    if ( messages.length == 0 ) clearInterval( tid )
    else console.log( messages.shift() )
  }, interval )
}

setMessageInterval( 500, 'J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't' )


fn.lengthで取得できる引数の長さにはRestパラメータの部分は含まれない。

var fn = (a, b, ...c) => {}

fn.length  // 2


Spreadコール [4.4.10]

関数コールの引数部分を『func( ...args )』と記述すると、argsがイテレータとして展開されて関数に渡される。
例:

var ary = [ 5, 15, 10 ]
console.log( Math.max( ...ary ) )  // 15

var set = new Set( ary )
console.log( Math.max( ...set ) )  // 15


また、new演算子と組み合わせることでコンストラクタ呼び出し時でも可変長引数が使える。
例:

var ary = [ 2015, 2, 1 ]

var date = new Date( ...ary )

// ES5: new (Function.prototype.bind.apply( Date, Array.prototype.concat.apply([,], ary )))


そして、通常の引数指定と組み合わせて一度に複数使うこともできる。
例:

setMessageInterval( 500, ...'JavaScript' )
console.log( Math.max( 1, ...[2, 3, 4], 5, ...[6, 7], 8 ) )  // 8


実装されるバージョン

V8 4.2.71(Rest) 4.4.10(Spread) 4.5.48(arrow) 4.5.71(デフォルト有効)