Help us understand the problem. What is going on with this article?

JavaScript 引数の数や型を動的に変更する方法まとめ

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('タマ') // タマ半端ないって
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away