2

後で動作を動的に変更できるように、コールバック関数をラップできるタイマー関数の作成を試み始めました。

これは、私がまだ関数を本当に理解していないこと、そして「これ」で何が起こっているのかを完全に理解していないことを一般的に認識することにつながりました

私はjsfiddleにテスト環境をセットアップしています

myns = {};
myns.somefunc = function(txt) {
    this.data = txt;
    this.play = function() {
        alert(this.data + ' : '+dafunc.data);
    };
};

var dafunc = new myns.somefunc('hello world');

myns.Timer = function(msec, callback) {
    this.callback = null;
    this.timerID = null;

    this.ding = function() {
        this.callback();
    };

    this.set1 = function( msec, callback ) {
        this.stop();
        this.callback = callback;
        this.timerID = setTimeout(this.ding, msec );
    };

    this.set2 = function( msec, callback ) {
        this.callback = callback;
        var wrappedDing = (function(who) {
            return function() {
                who.ding();
            };
        })(this);
        this.timerID = setTimeout(wrappedDing, msec );
    };
    //this.set1(msec, callback);
    this.set2(msec, callback);    
};

var ttimer = new myns.Timer(1000, dafunc.play);

set1 メソッドを使用すると、コールバックが機能しません。だから私は set2 メソッドを試しています。これで play メソッドにたどり着きますが、「これ」は somefunc のインスタンスを参照していません。

私は正しい方向に進んでいると思っていましたが、「これ」の混乱に混乱しています。

手がかりは大歓迎です。

4

1 に答える 1

1

問題は、Python のような言語とは異なり、dafunc.play を取得して別の場所 (callback = dafunc.play) に渡すと、dafunc に関連付けられていたことを忘れてしまうため、さらに別のラッパー関数を使用する必要があることです。 、 set2 関数で行ったように。

var ttimer = new myns.Timer(1000, function(){ return dafunc.play(); });

そこまで余計な機能を自分で作るのは面倒ですよね。代わりに、新しいブラウザーで利用できる bind メソッドを使用できます。

var wrappedDing = this.ding.bind(this);

new myns.Timer(1000, dafunc.play.bind(dafunc) );

または、古いバージョンの IE もサポートする必要がある場合は、同様の shim を使用できます。


最後に、何らかの形式の継承または動的バインディングを利用しない場合は、クロージャを使用するようにコードを書き直すことができます。thisすべてがレキシカル スコープであるため、もう心配する必要はありません。

(ところで、プロセスのコードを単純化してしまいました...)

myns = {};

myns.somefunc = function(txt) {
    var obj = { data : txt };
    obj.play = function() {
        alert(obj.data);
    };
    return obj;
};

var dafunc = myns.somefunc('hello world');

myns.timer = function(msec, callback) {
    var timerID = null;

    var set = function(){
        stop();
        timerID = setTimeout(callback, msec);
    };

    set();

    return { 
         set: set
    };
};

var ttimer = myns.timer(1000, dafunc.play);

最後にもう 1 つ: 出力にアラートを使用する代わりに、console.log とブラウザーのデバッガーおよび開発コンソールを使用してください。

于 2012-05-02T00:35:33.397 に答える