JavaScriptの技法:高度な関数の活用

文:Nick Gibson(Builder AU)
翻訳校正:原井彰弘
2008/01/10 07:00

JavaScriptに含まれている高度な関数を用いると、ウェブサイトをパワフルかつ迫力のあるものにできる。本稿では、再帰と参照渡し、および値渡しの利用方法を紹介する。

クラスのコンストラクタとしてのJavaScript関数

 JavaScriptの関数は、カスタムオブジェクトを作成する際にクラスのコンストラクタとして実行させることが可能である。クラスのインスタンスはnew演算子を用いて作成されるため、リストBでお見せしたFunction()コンストラクタを用いた例と同様に、thisキーワードを用いてそのオブジェクトを参照することが可能になる。この場合、クラスのコンストラクタ内でthisキーワードを使用することにより、クラスのインスタンスでメソッドやプロパティを持てる。リストDにその例を示そう。

リストD

function myMath() {
                                         //     Properties
       this.result;               //     Result of method

                                         //     Methods
       this.add = myAdd;                 //     Add method

       function myAdd(x,y) {
              this.result = x + y;

              return this.result;
       }
}

var math = new myMath();          //     Create an instance

alert(math.add(2,2));
alert(math.result);

可変長引数の関数

 今まで本稿で議論した関数は、すべて引数の数が固定されており、関数内では引数の名前によって参照されていた。しかし、ときには引数の数を可変にしたいこともあるだろう。次にその方法を示そう。

 たとえばリストAのadd関数を例に挙げると、add(2,2,2)の結果はadd(2,2)と同一になってしまい、利用者が予想した結果とは異なる可能性がある。このような場合、argumentsオブジェクトを利用すれば、関数で可変長の引数を扱えるようになる。具体的には、argumentsオブジェクトのlengthプロパティを使用し、argumentsオブジェクトをコレクションと見てアクセスすることで実現が可能だ。この例をリストEに示した。

リストE

function add(x,y) {
       var fltResult = 0;

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

       return fltResult;
}

 argumentsオブジェクトでは、calleeやcallerといったプロパティも提供している。calleeプロパティでは、現在のJavaScript関数への参照を保持している。一方、callerプロパティは現在の関数を呼び出した関数への参照を保持しているほか、argumentsオブジェクトが現在の関数の引数にアクセスするのと同様の方法で、プロパティを通して呼び出し元の引数にアクセスすることが可能になっている。従って、たとえば呼び出し元の関数の引数長はarguments.caller.lengthで参照できる。また、argument.caller[0]のようにしてコレクションにアクセスすると、最初の引数を参照できる。

 ところで、JavaScriptで引数を扱うときに注意しておかなければならないのは、new演算子によって定義されたオブジェクト以外は、引数はすべて値渡しであるということだ。従って、引数にオブジェクトを指定した場合以外は、引数に対して行われた操作は関数の実行が終了するとすべて消えてしまうのである。リストFに、引数を参照で渡した場合と値で渡した場合の違いを示した。

リストF

var x = 2;
 var y = new Array();
 y.push(3);
 document.writeln('initialize: x = ' + x + '<br />');
 byValue(x);
 document.writeln('initialize: x = ' + x + '<br />');
 document.writeln('initialize: y[0] = ' + y[0] + '<br />');
 byReference(y);
 document.writeln('initialize: y[0] = ' + y[0] + '<br />');
 function byValue(x) {       x += 2;       document.writeln('byValue: x = ' + x + '<br />');
 }
 function byReference(y) {       y[0] += 3;       document.writeln('byValue: y[0] = ' + y[0] + '<br />');
 }

 さて、最後は再帰だ。

記事の感想やご意見をコメントでお寄せください(CNET_IDログインが必要です)
ログイン パスワードを忘れた方  |  新規登録
  • 今日のトップ記事
  • 昨日
  • 2日前
  • 3日前
  • 6日前
  • 7日前
  • 新着記事
  • 人気記事
  • 特集
  • ブログ