| sub | return | main | x | |
1 | sub(a, b=10) | a+b | x=sub(1) | 11 | 通常引数。省略時指定 |
2 | sub(a, b=10) | a+b | x=sub(1, 2) | 3 | 省略しないとき |
3 | sub(a, {b=10}) | a+b | x=sub(1, {b:2}) | 3 | 名前付き引数 |
4 | | | x=sub((1, {b=2})) | エラー | b:2 の形式にする |
5 | sub(a, {b=10}) | a+b | x=sub(sub(1, {}) | 11 | |
6 | sub(a, {b=10}) | a+b | x=sub(1) | エラー | { } は省略不可 |
7 | sub(a, {b=10, c=20}) | a+b+c | x=sub(1,{c:3}) | 14 | |
8 | sub(a, {b=10, c=b}) | a+b+c | x=sub(1, {}) | 21 | 省略値を変数で与える |
9 | sub(a, {b=10, c=b}) | a+b+c | x=sub(1, {b:2}) | 5 | |
10 | sub(a, {b=10, c=b}) | a+b+c | x=sub(1, {c:3}) | 14 | |
11 | sub(a, {b=[10]}) | a+b[0] | x=sub(1,{b:[2]}) | 3 | 名前付関数が配列 |
12 | sub(a, {b=[10]}) | a+b[0]+b[1] | x=sub(1,{b:[2]}) | エラー | b[2] が未定義 |
13 | sub(a, {b=[10]}) | a+b[0]+b[1] | x=sub(1,{b:[2,3]}) | 6 | 配列のサイズは可変 |
14 | sub(a, {b=[10,20]}) | a+b[0]+b[1] | x=sub(1,{b:[2]}) | エラー | b[2] が未定義 |
15 | sub(a, options) | a+options.b | x=sub(1, {b:2}) | 3 | 名前付き引数を変数にする。option.引数名になる |
16 | sub(a, options{b}) | a+options.b | | エラー | sub側に変数を指定できない |
例0:ここでの例題
次の関数0は、自然数(1, 2, 3, …)の「最初」「最後」「間隔」(キザミ幅)を与えて、その合計をダイアログボックスに表示します。
関数0の引数はすべて位置固定引数ですが、関数1以降で同じ内容の処理を名前付引数にする場合を検討します。
function 関数0(最初, 最後, 間隔) {
var 合計 = 0;
for (var i = 最初; i <= 最後; i += 間隔) {
合計 += i;
}
alert(合計);
}
→4+6+8=18→18 が表示される
例1:名前付引数の記述方法
名前付引数では、計算する関数「関数1」とメイン関数「例0」の引数を次のように記述します。
関数: function 関数1(引数) {
… …
}
呼出: 関数1( {最初: 4, 最後: 8, 間隔: 2} );
- 関数の記述形式
- 関数1には、必ず仮引数「引数」(名称は自由)を入れる。
例1で「最初: 4」とすると、関数1では「引数.最初」の値が4になる。
- 例1では、名前付引数のリストを {…} で囲まなければならない。
- 実引数の記述形式
- 実引数の省略とデフォルト設定
- 実引数を省略することができる。
例えば「間隔」を省略して、 関数1( {最初: 4, 最後: 8} ); とすることができる。→ケース3
すべての引数を省略する場合も 関数1( { } ); とする必要があり、関数1( ); ではエラーになる。→ケース4
- 省略した引数には、関数1で設定したデフォルト値になる。
デフォルト設定の方法
呼び出された側の関数では、変数「仮引数名.実引数名」として値を受け取ります。関数内で変数名をそのまま使うのは煩雑なので、次のように関数内で使う変数を定義するのが適切です。
var 変数名 = 仮引数名.実引数名;
例1で「最初: 4」とすると、関数1では「引数.最初」となるので、例えば
var 最初 = 引数.最初;
として、関数1内では変数「最初」を使うことにする。
省略された引数は、値が undefined(未定義)になっている。それにデフォルト値を設定するには、
if (変数 === undefined) 変数 = デフォルト値;
とすればよい。
(undefined(未定義)と Null とを明確に区別するために == ではなく、===(厳密等価演算子)を用いている。)
関数1
関数1では、すべての引数を名前付引数とし、その引数名を「引数」としました。
そして「最初」を1、「最後」を10、「間隔」を1にデフォルト設定しています。
function 関数1(引数) {
// 引数変数の定義
var 最初 = 引数.最初;
var 最後 = 引数.最後;
var 間隔 = 引数.間隔;
// デフォルト値の設定
if (最初 === undefined) 最初 = 1;
if (最後 === undefined) 最後 = 10;
if (間隔 === undefined) 間隔 = 1;
// 計算
var 合計 = 0;
for (var i = 最初; i <= 最後; i += 間隔) {
合計 += i;
}
alert(合計);
}
ケース1
すべて指定 4+6+8=18が表示される
ケース2
順序の変更ができる 4+6+8=18が表示される
ケース3
「間隔」を省略(デフォルト値=1)4+5+6+7+8=30が表示される
ケース4
すべて省略 1+2+・・・+10=55が表示される
ケース4の{}は必要です。単に 関数1(); とするとエラーになります。その回避方法は例3で示します。
例2:固定位置引数と名前付引数の混在
引数のうち必須な変数は固定位置引数とし、省略可能な変数は名前付引数とするのが通常でしょう。
関数2では「最初」を固定位置引数とし、「最後」と「間隔」を名前付引数としました。
function 関数2(最初, 引数) {
// 引数変数の定義
var 最後 = 引数.最後;
var 間隔 = 引数.間隔;
if (最後 === undefined) 最後 = 10;
if (間隔 === undefined) 間隔 = 1;
// 計算
var 合計 = 0;
for (var i = 最初; i <= 最後; i += 間隔) {
合計 += i;
}
alert(合計);
}
ケース1
位置固定引数で「最初」は4、名前付引数で「最後」を8、「間隔」は指定していないのでデフォルト値の1
4+5+6+7+8=30が表示されます。
ケース2
「最初」は4、名前付引数が空なので「最後」が10、「間隔」が1になる
4+5+・・・+9+10=49が表示されます。
ケース3
名前付引数がないので、「var 最後 = 引数.最後;」がエラーになります。
例3:名前付引数を与えないときの回避
例1のケース4、例2のケース3のエラーを回避するには、関数3のように (引数 === undefined)の処理を加える必要があります。
function 関数3(最初, 引数) {
// 引数変数の定義
if (引数 === undefined) {
var 最後 = 10;
var 間隔 = 1;
}
else {
最後 = 引数.最後;
間隔 = 引数.間隔;
if (最後 === undefined) 最後 = 10;
if (間隔 === undefined) 間隔 = 1;
}
// 計算
var 合計 = 0;
for (var i = 最初; i <= 最後; i += 間隔) {
合計 += i;
}
alert(合計);
}
ケース3
これで正しく49が表示されます。
なお、例2のケース1やケース2も関数3で正しく処理されます。