javascriptのクラスの作成とsetTimeout

javascriptで自作のclassを作成する際に、けっこうはまったので、メモ。


なまじJavaの経験があって、なまじjavascriptという名前が付いているために同じ感覚で作っていってけっこうはまった。


以下、簡単なサンプルの抜粋

クラスを定義したjsファイル内

function TesObj(num){
    this.initialize.apply(this,arguments);
}

TestObj.prototype = {
    initialize: function(num) {
        this.num = num;
    },

    funcA: function() {
        setTimeout(this.funcC,1000);
    },

    funcB: function() {
        this.funcC();
    },

   funcC: function() {
        alert("ccc");
        alert(this.num);
   }
	
}


呼び出し元のHTML内

var obj = new TestObj(777);
function testA(){obj.funcA();}
function testB(){obj.funcB();}
function testC(){obj.funcC();}


<input type="button" value="A" onclick="testA();"/> ⇒"ccc"、"undefined"となる
<input type="button" value="B" onclick="testB();"/> ⇒"ccc"、"777"となる
<input type="button" value="C" onclick="testC();"/> ⇒"ccc"、"777"となる


なぜtestA()だけうまく動かない???


色々、調べていくと

メソッドの呼び出しは「親オブジェクト」を this として渡し、関数の呼び出しはグローバルオブジェクトを this として渡します。

というそれっぽい記述を発見。
まだ上手く説明できないけど、setTimeoutを使うと、呼び出された関数内のthisというのはグローバルオブジェクトになるということ。確かにalertでデバックした結果と一致する。testBの場合はメソッドの呼び出しということで、親オブジェクトがthisとなっている。


funcAを以下のように、コールバックを無名関数に変更することで、メソッドの呼び出し扱いとなり、"777"が表示されるようになる。

funcA: function() {
      var me = this;
      setTimeout(function(){me.funcC();},1000);
},


うーん、まだ自分の中でもちゃんとまとまっていないな。。帰ったらちゃんとまとめよう。



大変、参考になったURL
http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Reference:Operators:Special_Operators:this_Operator
http://d.hatena.ne.jp/amachang/20060910/1157911122
http://d.hatena.ne.jp/amachang/20060516/1147778600