概要
前回のブログ記事は関数の引数を省略した場合の挙動を試しましたが、
今回の記事は、関数の呼び出し元が引数の数を多く書いた場合の挙動を試してみます。
まずは実際のコードを書いて動きを試してみます。
function test3(a, b) { console.log(a); console.log(b); if (a == undefined) { console.log("a1"); } else { console.log("a2"); } if (b == undefined) { console.log("b1"); } else { console.log("b2"); } } test3(10, 20, 30);
出力結果
10 20 a2 b2
上記のような出力結果になりました。
関数test3の第三引数の「30」は引数として解釈不可能なので、
エラーにもならず、関数内では何もなかったかのような挙動になります。
関数の挙動について
それでは、上記のような関数内で、第三引数が存在する呼び出し方をした場合に処理するにはどうすればよいかというと、
javascriptのArgumentsオブジェクトを利用する方法があります。
Argmentsオブジェクトは配列のように振る舞い、引数の値はarguments[]配列に格納され、それを関数内で使うことができます。
具体的には次のようなコードを書いて試してみます。
function test4(a, b) { console.log(a); console.log(b); console.log(arguments[0]); console.log(arguments[1]); console.log(arguments[2]); } test4(10, 20, 30);
出力結果
10 20 10 20 30
出力結果を見ればわかりますが、test4の関数の引数は2つしか定義していませんが、arguments[2]という書き方をすることにより、Argmentsオブジェクトを使い、引数の3つめの値が取得できています。
現場のプログラミングでは、関数の引数の数は、設計や仕様に基づいて正確に書くことが大半ですが、
引数の数を限定しない仕様で関数を定義すると便利な場合があります。
例えばmax関数で引数があればあっただけ、その中から最大値を求める場合の関数はその例です。
また、任意の引数を受け取ることができる関数を、可変長引数関数と呼びます。
別名としてvarargs関数と呼んだりもします。
calleeプロパティ、callerプロパティ
Argmentsオブジェクトについては、配列のように使う方法に限らず、その他の動きをするプロパティもあります。
use strictの状態ではエラーになりますが、非strictモードの場合はcalleeプロパティ、callerプロパティというプロパティが使用できます。
calleeプロパティは関数を呼び出した関数を参照できます。
callerプロパティは匿名関数にて、自分自身を再帰的に呼び出せます。