6

完了時に関数をコールバックする高価な初期化プロセスを持つオブジェクトの OO JavaScript を作成しようとしています。

問題は、呼び出し元がコールバック ルーチンで同じオブジェクトの関数を使用する必要があり、そのオブジェクトがまだ存在しないことです。

// ctor for foo object
function foo(callback) {

    // do slow initialization here..

    // callback when done
    callback();
};

foo.prototype = function() {

    return {
        // doStuff method
        doStuff: function() {
          alert('stuff done');
        }
    };        
}();

// instantiate the foo object, passing in the callback
var f = new foo(function() {

    //Uncaught TypeError: Cannot call method 'doStuff' of undefined 
    f.doStuff();

});​

jsFiddle ここで何が欠けていますか?

4

3 に答える 3

7

これは簡単な修正である必要があります。まず、this現在のオブジェクトに設定されたオブジェクトでコールバックが呼び出されていることを確認してください

function foo(callback) {
    // do slow initialization here..

    callback.call(this);
};

次に、コールバックの方法を調整します

var f = new foo(function() {
    this.doStuff();
});​

これが更新されたフィドルです

于 2012-12-22T04:05:57.127 に答える
2

これが機能しない理由は次のとおりです。JavaScript がコードを実行しているとき、設定する前に、式fを評価する必要がありnew foo(...)ます。コンストラクター内で、コールバックを呼び出します。f式がまだ終了していないため、JavaScript はまだ設定されていません。コンストラクターが終了するとすぐに、正しく設定されますが、コールバック内でf使用しようとするため、そこには到達しません。fundefined


イベントループを介して次の反復でコールバックを呼び出すことができます。

callback();

あなたがするだろう:

setTimeout(callback, 0);

ただし、これは、非同期で完了すると既に想定している場合にのみ機能します。

于 2012-12-22T04:07:23.140 に答える
2

あなたのアプローチは本質的な問題です。コンストラクター内で doStuff を定義します。そのような呼び出し:

var f = new Foo();
f.doStuff();

新しいオブジェクトが作成されるたびに実行する init メソッドを作成することもできます。ただし、コンストラクターのスコープ内でこれを行う必要があります... コンストラクターにコールバックを渡さないでください。

于 2012-12-22T04:09:48.483 に答える