javascript学習の関数-パラメータ


javascript関数は任意の複数のパラメータで呼び出すことができます.関数の定義を管理することなくいくつかのパラメータを指定しました.関数は弱いタイプなので、その所望のパラメータタイプを宣言する方法はなく、どの関数にもどのタイプの値を伝えることが合法的です.
オプションのパラメータ
関数を呼び出した場合、伝達パラメータは宣言時のパラメータよりも少ないです.追加のパラメータはundefined値で処理されます.呼び出し時に無視されたり、オプションの関数を書いたりすることも有用です.この目的を達成するには、無視されるかもしれないパラメータに合理的な値(またはnullに指定)を割り当てる必要があります.
//オブジェクトoの属性名をすべて配列aに追加し、配列aを返します.oが無視されている場合は、まず作成してから戻ります.

function copyPropertyNamesToArray(o,a)//   ,a    
{
if(!a) a=[];//          ,       
for(var property in o) a.push(property);
return a;
}
このように関数を定義すると、非常に柔軟に呼び出すことができます.

var a=copyPropertyNamesToArray(o);//  o           a 
copyPropertyNamesToArray(p,a);//   P      a 
上記の関数の最初の行のコードを、二重縦線オペレータ𞓜という言語習慣に適合する方法で置換することができる.
a=a𞓜𞓜[]
注意:もし𞓜|の最初のパラメータの値がtrueであるか、またはtrueに変換されると、この操作は最初のパラメータに戻ります.そうでないと、第二のパラメータに戻ります.ここでaが定義されていないと、aはnullではなく、aはemptyでも、aに戻ります.そうでないと、空の配列に戻ります.
注意関数を設計するときは、オプションのパラメータがパラメータリストの最後にあることを確認してください.プログラマは、最初のパラメータを無視して、2番目のパラメータに入ることができません.
変数の長さのパラメータリスト:パラメータオブジェクト
関数の体内では、argments識別子は特別な意味を持っています.argmentsはAgmentsオブジェクトを指す特殊な属性です.Agmentsオブジェクトは行列式のオブジェクトです.名前ではなく関数に渡すパラメータを数字で検索することができます.彼もcalee属性を意味します.
関数を定義する際に固定のパラメータの個数を指定していますが、呼び出し時には任意のパラメータが入力されます.これらのパラメータにはAgmentsオブジェクトが完全にアクセスできます.一部またはすべての名前なしのものもあります.一つのパラメータxの関数fを定義すると、呼び出し時には二つのパラメータが入力されます.最初のパラメータはxまたはargmenを簡単に通過できます.ts[0]を取得します.2番目のパラメータはargmentts[1]でしか取得できません.また、本当の配列のように、argmentsはlength属性が含まれている要素の個数を指定しています.したがって、関数fの内部では、argments.lengthの値は2です.
argmentsオブジェクトは多くの場合に有用です.以下の例は、実用的で正確な数を証明するためにどのようなパラメータで関数を呼び出すかを示します.
function f(x,y,z)

{

//               

if(arguments.length !=3)

{throw new Error("function f called with "+arguments.length+"arguments, but it expects 3 arguments.");}

…

}
argmentsオブジェクトは、javascript関数について、任意のパラメータを受信し、その最大値を返すように書くことができる可能性があります.(内蔵関数Math.max()と同様に、同じ働き方をしています.
function()

{

    var m=Number.NEGATIVE_INFINITY;

    //       ,      。

    for(var i=0;i<arguments.length;i++)

    {

        if(arguments[i]>m) m=arguments[i];

    }

     return m;

}

var largest=max(1,2,3,4,54);
このような関数は無参照呼出しを禁止しています.argments[]オブジェクトを使って固定パラメータを書いてから有可能なパラメータを追加しても良いです.
覚えてください.argmentsは本物の配列ではなく、argmentsオブジェクトです.それぞれのargmentsオブジェクトは、限られた要素の個数とlength属性を定義しています.技術的には、配列ではありません.限られた属性のオブジェクトとして理解できます.
argmentsオブジェクトには特徴があります.一つの関数に名前が付いているパラメータがある場合、argmentsオブジェクトの配列要素は関数パラメータ名の同義語です.argments[]とパラメータ名は同じ変数を呼び出す2つの方法です.パラメータ名でパラメータを変更する値は同様にargments[]配列要素の値を変更します.逆も同じです.
function(x)

{

    print(x); //         。

    arguments[0]=null;

    print(x);//     null

}
これは、argmentsが通常の配列ではないことを証明しています.そうでなければ、argments[]とxは初期化された値と同じですが、一つの変更は他の配列に影響を与えません.
calee属性
配列要素以外にも、argmentsオブジェクトは、実行される関数を指すcalee属性を定義しています.この属性はあまり使われません.しかし、名前のない関数は再帰的に自分を呼び出すことができます.
function(x)

{

if(x<=1) return 1;

return x*arguments.callee(x-1);

}
オブジェクトの属性をパラメータとして扱う
一つの関数が3つ以上のパラメータを必要とする場合、引数の正確な順序を覚えるのは非常に難しいです.このような関数を呼び出すたびに一度の関数を調べて、一度の関数説明書の苦境から救い出すためには、順序を無視したキーペアの形でパラメータを伝えるのが良い方法です.このアイデアを有効にするためには、関数を受信として定義する必要があります.単独のオブジェクトをパラメータとして入力し、キーペアを定義したobject literalにユーザが入ります.
//  from   from_start      length    to    to_start  ,         
function arraycopy(/*array*/ from,/*index*/ from_start,/*array*/to,/*index*/ to_start,/*integer*/ length){…}
改善された関数を見てください.

function easycopy(args)
{
    arraycopy(args.from,
                   args.from_start||0,//            0
                   args.to,
                   args.to_start||0,
                   args.length);
}
      easycopy:
var a=[1,2,3,4];
var b=new Array(4);
easycopy({from:a,to:b,length:4});
パラメータの種類
javascriptは弱いタイプの言語なので、メソッドのパラメータはタイプを宣言できません.また、送信された値のタイプをチェックしていません.コードを作成する時に記述性のある名前を書いてもいいです.コメントでパラメータを表記するタイプもあります.arraycopy関数のように、オプションのパラメータについては、コメントに「optional」を追加できます.このような単語は、一つの方法で複数のパラメータを受け入れると、次のようになります.
function max(/*number…/){}
javascriptでは、タイプ変換は非常に自由です.関数を書いて文字列パラメータを受信して他のタイプで呼出しすると、入力した値は文字列に変換されます.元のタイプはすべて文字列に変換されます.すべてのオブジェクトにtoString()方法がありますので、このようなエラーは永遠に発生しません.
しかし、必ずしもそうではありません.arraycopy関数を見てください.最初のパラメータは配列です.もし入ってきたのが配列ではないなら、実行は失敗します.このようなエラーをチェックするためにコードを追加します.間違ったパラメータが入ったら、例外を投げて説明してください.これは失敗した時よりも味わいがいいです.

//     (      )       
//              ,null   undefined    
function sum(a)
{
   if( (a instanceof Array)||(a && typeof a == "object" && "length" in a))//               object
   {
        var total=0;
        for(var i=0;i<a.length;i++)
        {
             var element=a[i];
             if(!element) continue;//   null   undefined
             if(typeof element == "number") total+=element;
             else throw new Error("sum(): all array elements must be numbers");
        }
        return total;
    }
    else throw new Error ("sum(): argument must be an array");
}
以上のsumは、流入したパラメータを非常に厳密に検討しながら、同様の配列を受信し、nullおよびundefined要素を無視することができる.
javascriptは文法が非常にゆったりしている弱いタイプの言語で、パラメータの種類と個数に対して非常にゆったりした関数を書くことができます.

function flexisum(a)
{
    var total=0;
    for(var i=0;i<arguments.length;i++)
    {
           var element=arguments[i];
           if(!element) continue; //   null   undefined
           var n;
           switch (typeof element)
           {
                 case "number":
                       n=element;
                       break;
                 case "object":
                         if(element instanceof Array) n=flexisum.apply(this,element);
                         else n=element.valueOf();
                         break;
                  case "function":
                         n=element();
                         break;
                  case "string":
                         n=parseFloat(element);
                         break;
                   case "boolean":
                          n=NaN;
                          break;
           }
           if(typeof n=="number" && !isNaN(n) total+=n;
           else throw new Error("sum(): can't convert "+element+" to number");
    }
    return total;
}