Vuexのコード読んでたらオプション引数を前に持ってくる実装があったので単発で
短い記事起こししようと思いましたが、せっかくなので他の方法も合わせてまとめました。
ダーっと書いたので、カバーできてないパターンがあったらコメント下さい。
オプション引数が後ろに来るやつ
実装方法1
ES6で書くならこれ一択です。一番基本的なやつですね。
引数宣言にイコールとデフォルト値を追加するだけです。
// 実装
function multiply (a, b = 1) {
return a * b
}
// 使用
multiply(5, 2) // 10
multiply(5) // 5
多分みんな知ってると思いますが、一つでもオプション引数を作ったらそれ以降の引数は
すべてオプション引数にしなければなりません。
// 関数の定義自体はできるが
function multiply (a, b = 1, c) { return a * b * c}
// 使い方が存在しない
multipty(5,,2) // 無理
実装方法2
ES6が使えないならこれ。falsyな値ガード。
よく見る実装ですがハマるときは本当にハマるので使う場合には
引数を渡さなかった際にデフォルト値を使う場合の注意点の内容を理解しておく必要あり。
// 実装
function multiply (a, b) {
b = b || 1
return a * b
}
// 使用
multiply(5, 2) // 10
multiply(5) // 5
オプション引数が前に来るやつ
例: VuexのmapXXX
// 名前空間の有り無しで本題の引数である配列が第一引数に来るか第二引数に来るかが変化する
mapState('bar', ['value']) // 名前空間あり
mapState(['value']) // 名前空間なし
実装方法
アタマの引数の型を確認し、それにより後ろの引数をスライドすればOK。
(Vuexのコードを参考にしました。)
// 実装
function method1 (arg1, arg2) {
if (typeof arg1 !=='string') {
arg1 = arg2
arg2 = null
}
// 処理を書く
}
// 使用
method1('someNamespace', ['hoge', 'fuga', 'piyo', 'nyaa']) // オプション引数あり
method1(['hoge', 'fuga', 'piyo', 'nyaa']) // オプション引数なし
★注意★
これをやるならドキュメントをしっかり書きましょう。
個人的にはこの系統のメソッドは使う側がどツボにハマる可能性があるので、あまり好きではないです。
引数の数が不定なやつ
例: いくつでも足し算出来るメソッド
sum() // 0
sum(2, 3) // 5
sum(2, 3, 4) // 9
実装方法1
ES6であればこちら。引数名の頭に...
をつけると、配列として受け取れます。
// 実装
function sum (...numArr) {
return numArr.reduce((s, n) => s + n, 0)
}
// 使用
sum() // 0
sum(2, 3) // 5
sum(2, 3, 4) // 9
また、最初の何個かは固定で残りが不定という形をとることもできます。
function f(a, b, ...theArgs) { // なんらかの実装 }
実装方法2
ES6でなければこちら。
引数部分には何も書かず、すべてのメソッドに自動的に用意される
ローカル変数のargumentsオブジェクトを参照しましょう。
★注意★ こいつ、Arrayと見せかけてArrayではない!!
知ってれば色々出来るので、興味のある人はこちらも見てみて下さい。
このargumentsに、使用側が渡した順に引数が入ってます。
// 実装
function sum() {
var s = 0
for (var i=0; i < arguments.length; i++) {
s += arguments[i]
}
return s
}
// 使用
sum() // 0
sum(2, 3) // 5
sum(2, 3, 4) // 9
引数が文字列でもクラスインスタンスでも良いやつ
ruby使いの人が好きなパターンなのか、ruby on railsでよく見るやつです。
例: 半端ない宣言をするメソッド
var cat1 = new Cat('大迫')
hampaNaiCat(cat1) // 大迫半端ないって
hampaNaiCat('タマ') // タマ半端ないって
実装方法
instanceof
で渡された引数がクラスインスタンスかどうかを判別します。
// 実装
hampaNaiCat(arg) {
const name = (arg instanceof Cat) ? arg.name : arg
return name + '半端ないって'
}
// 使用
class Cat {
constructor(name) {
this.name = name;
}
set name(name) {
this._name = name;
}
get name() {
return this._name;
}
}
var cat1 = new Cat('大迫')
hampaNaiCat(cat1) // 大迫半端ないって
hampaNaiCat('タマ') // タマ半端ないって