setTimeoutの話

まーenchant.jsに限る話ではありませんが。

一定時間後にある関数を実行してくれる「setTimeout」、便利ですよね。
私も結構使っています。
ですがこの関数、ちょっと使い方にコツがあるんです。
例えば以下のようなクラスがあったとします。

TScene = enchant.Class.create(enchant.Scene, {
    initialize : function() {
        enchant.Scene.call(this);
        this.msg = "test";
        setTimeout(this.print, 1000);
    },
    print : function() {
        console.log(this.msg);
    }    
});

これ、ちゃんと出力はされません。
何故って「this.msg」が未定義だから。
setTimeoutで実行される空間はTSceneの空間とは切り離された世界になります。
なのでTSceneに属するthis.msgはsetTimeoutで呼び出すコールバック関数では利用できません。
ではどうするか。
答えはこうです。

TScene = enchant.Class.create(enchant.Scene, {
    initialize : function() {
        enchant.Scene.call(this);
        this.msg = "test";
        setTimeout(this.print, 1000, this);
    },
    print : function(self) {
        console.log(self.msg);
    }    
});

setTimeout関数の第三引数以降は、コールバック関数の引数とみなされます。
ですので、コールバック関数に引数受けを用意し、第三引数で自分自身をコールバック関数に渡してやればTSceneの変数や関数を利用することが可能になります。
定期的に実行する場合は以下のようにするといいでしょう。

TScene = enchant.Class.create(enchant.Scene, {
    initialize : function() {
        enchant.Scene.call(this);
        this.msg = "test";
        this.endflg = false;
        setTimeout(this.print, 1000, this);
    },
    print : function(self) {
        console.log(self.msg);
        if (!self.endflg) setTimeout(self.print, 1000, self);
    }    
});

this.endflgがtrueになるまでprint関数が実行されます。