引数を渡さなくてもいいし、渡すことでオプション設定できるような処理を考える。
javascriptだと可変長引数の関数を書く方法が色々とあるので、それぞれ書いてみてどれを使うのがいいか考えてみます。
比較的新しい書き方もありますが使えない環境はそうそうないと思う。Babelは偉大。
1.引数で代入する
1 2 3 4 5 6 7 8 |
const func1 = (a = 0, b = 1, c = 2) => { console.log(a, b, c); }; func1(); //0 1 2 func1(9); //9 1 2 func1(9, 9); //9 9 2 func1(9, 9, 9); //9 9 9 func1(9, 9, 9, 9); //9 9 9 |
引数省略で後半のパラメータをデフォルト値にすることが出来る。
関数自体は書きやすいけど使う側で何を渡していいか迷うこともある。
2.スプレッド構文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const func2 = (...arr) => { if (arr.length < 1) { arr = [0, 1, 2]; } else if (arr.length < 2) { arr.push(1, 2); } else if (arr.length < 3) { arr.push(2); } console.log(arr); }; func2(); //[ 0, 1, 2 ] func2(9); //[ 9, 1, 2 ] func2(9, 9); //[ 9, 9, 2 ] func2(9, 9, 9); //[ 9, 9, 9 ] func2(9, 9, 9, 9); //[ 9, 9, 9, 9 ] |
...
)を付けてオブジェクトを展開する演算子があります。
これを引数に用いた場合は逆に複数引数を配列として扱うことが出来る。
書き方によって引数の前省略や後省略などできるので可変引数としての自由度は高いが関数自体が読みにくくなってしまう。
配列のインデックスをキーとして考えると、こう書くこともできる。
1 2 3 4 5 6 7 |
const func2b = (...arr) => { let useArr = { ...[0, 1, 2], ...arr }; console.log(useArr); }; func2b(); //{ '0': 0, '1': 1, '2': 2 } func2b(9); //{ '0': 9, '1': 1, '2': 2 } func2b(9, 9, 9, 9); //{ '0': 9, '1': 9, '2': 9, '3': 9 } |
とはいえこんな書き方は見たことはない。
3.Argumentsオブジェクトを使う
1 2 3 4 5 |
function func3() { console.log(arguments); } func3(1); //[Arguments] { '0': 1 } func3(1, 2, 3); //[Arguments] { '0': 1, '1': 2, '2': 3 } |
Array風のオブジェクトなので適当に変換してからスプレット構文時と同様に使う。
かなり昔のNode.jsプラグインでよく見た気がするけど最近では全く見ない。
色々書く方法がある中でもうこれを使うメリットはないように思う。
4.Javascriptオブジェクトのマージ
1 2 3 4 5 6 7 8 9 10 11 12 |
const defaultOption = { a: 0, b: 1, c: 2 }; const func4 = opt => { let useOpt = { ...defaultOption, ...opt }; console.log(useOpt); }; func4(); //{ a: 0, b: 1, c: 2 } func4({ b: 9 }); //{ a: 0, b: 9, c: 2 } func4({ d: 9 }); //{ a: 0, b: 1, c: 2, d: 9 } |
これまでと違って引数の順序を気にする必要がない。
関数側も使う側もわかりやすく使いやすい。一番好き。
5.オブジェクトキーを変数として利用+初期化
1 2 3 4 5 6 7 |
const func5 = ({ a = 0, b = 1, c = 2 }) => { console.log(a, b, c); }; func5({}); //0 1 2 func5({ b: 9 }); //0 9 2 func5({ d: 9 }); //0 1 2 //func5(); //TypeError: Cannot destructure property `a` of 'undefined' or 'null'. |
つまりこういうことが出来る。
1 2 3 4 |
const func5b = ({ a: d = 0, b: e = 1, c: f = 2 }) => { console.log(d, e, f); }; func5b({ b: 9 }); //0 9 2 |
まあ読みにくいだけなのですることはないと思います。
マージするわけではないので必要ない部分(d
)は無視されます。
また引数にオブジェクトは必須で空で呼び出すとundefined
エラー。
これも思いついたはいいけど見たことはない。