【javascript】関数で可変長引数を扱う

処理の中で関数の引数の総数が定まらない場合があります。
これを可変長引数と言います。

ja.wikipedia.org

可変長引数を扱いたい場合は、追加したい要素を配列にしてしまう方法もあります。

// 指定された数字の合計値を返す
function sum(args) {
    return args.reduce((accumulator, currentValue) => {
        return accumulator + currentValue;
    })  
}

// 配列を関数に渡す
let args = [1, 2, 3];
console.log(sum(args));

配列にする事で要素の数に関係なく、引数に指定できます。
この方法以外でも可変長引数を扱う事はできます。

今回は、関数にそのまま単体のデータをいっぺんに渡して処理する方法について記述します。

既存の関数で使用されている可変長引数

既存の処理でも引数の数が決まっていないものもあります。
例えば、オブジェクトを結合する関数にObject.assign()というものがあります。

developer.mozilla.org

この関数も、対象のオブジェクト(target)に対して、結合したいオブジェクト(source)を複数指定する事が出来ます。

// Object.assign(target, ...sources)

Object.assign(target, source1, source2, source3, .... sourceX)

残余引数

前述したソースの様に、...(三点リーダー)の引数を指定する事で、自作の引数でも複数の引数を並列で設定する事ができます。
この指定方法を、スプレッド構文と言います。   developer.mozilla.org

そして、不定数の引数の事をjavascriptでは残余引数、またはRest Parametersと言います

developer.mozilla.org

残余引数を用いた実装例

冒頭で書いたソースを残余引数を使った形式に書き換えます。

// 指定された数字の合計値を返す
function sum(...args) {
    return args.reduce((accumulator, currentValue) => {
        return accumulator + currentValue;
    })  
}

// 直接要素を連続して指定
console.log(sum(1, 2, 3, 4, 5, ... X));

応用

残余引数の前に単体の引数を指定する事で、引数を分ける事も可能です。

// 第一引数は文字型、以降に指定した要素は配列にする
function initValue(name, ...args) {
   // nameにBobが代入され、以降の数字は...argsに代入されます。  
}

initValue('Bob', 1, 2, 3, 4, 5, ... X);

使用上の注意

残余引数の後に別の引数を指定する事はできません。
残余引数を用いる場合は関数の最後に指定する必要があります。

// ..argsの後に、単体の引数は指定できません。
function initValue(name, ...args, address) {
   //...
}

// これは出来ない
initValue('Bob', 1, 2, 3, 4, 5, ... X, 'Tokyo');

Tips

【Array.prototype.reduce()】前回の結果を引き継いで同じ処理をする

今回作成したコードではArray.prototype.reduce()を用いて配列の合計値を出しました。
この関数を使用する事で、配列を元に結合した結果を得る事もできます。
developer.mozilla.org

map()と似てはいますが、mapは元の配列を元にした新しい配列を返すのに対して、 reduce()は結果を1つ返します。

developer.mozilla.org

つまり、今回書いたコードの様に数字の配列に対して使用すれば、その数字を関数内で処理し続けた結果が帰ってくるというわけです。

// 指定された数字の合計値を返す
function sum(...args) {
    return args.reduce((accumulator, currentValue) => {
        return accumulator + currentValue;
    })  
}
console.log(sum(1, 2, 3, 4));
// 1.   1 + 2 = 3(次のaccumulatiorへ)
// 2.   3 + 3 = 6(次のaccumulatiorへ)
// 3.   6 + 4 = 10
//
// 戻り値は10

©︎2017-2018 WebSandBag