スタートページJavascript関数への引数渡し

名前付引数

通常の関数では、
  function 関数(引数1, 引数2, 引数3, ・・・, 引数n) {
      ・・・
  }
の形式で定義され、それを呼び出すには、
  関数(1, 2, 3, …, n);
とします。このように引数の位置が固定している引数を位置固定引数といいます。

位置固定引数の形式では、引数の個数が大きく、しかも省略して標準値(デフォルト値)を使うことが多い場合、最後のほうの引数に値を指定するのは厄介です。
  「引数i=12」「引数j="ABC"」
というような指定ができれば便利です。このような引数の指定方式を名前付引数といいます。


まとめ

例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. 関数の記述形式
  2. 実引数の記述形式
  3. 実引数の省略とデフォルト設定

デフォルト設定の方法

呼び出された側の関数では、変数「仮引数名.実引数名」として値を受け取ります。関数内で変数名をそのまま使うのは煩雑なので、次のように関数内で使う変数を定義するのが適切です。
    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で正しく処理されます。


 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側に変数を指定できない