2

オブザーバー/リスナー システムをセットアップしたい:

var listeners = [];

function MyObj(){
    this.myMethod = function(){
        // react to event
    }
}

var myObj = new MyObj();

function addListener(fn, obj){
    alliancesNotify[alliancesNotify.length] = {fn: fn, obj: obj}
}

addListener(myObj, myObj.myMethod); // Best way of doing it?

function notify(objArr){
    for (var i in objArr){
        objArr[i].obj.fn(); // will this work? 
    }
}

notify(listeners);

コメントされた 2 行についてのご意見 (実際に期待どおりに機能するかどうか) と、メソッドを呼び出してオブジェクトに通知するより簡単な方法があるかどうかを期待していました。(たとえば、一部の実装では、この方法ではなく、関数への参照ではなく文字列として関数名を渡すことに気付きました。)

ありがとう

4

2 に答える 2

2

まず第一に、複数の問題があります。それらを 1 つずつ取り上げます。

  • objArr[i].obj.fn();あなたが期待することをするつもりはありません。myMethodfn メソッドを探して呼び出しますが、objから呼び出すのを楽しみにしていました。これを修正するには、複数のオプションがあります。applyまたはを使用しますcall。したがって、コードは次のようになりますobjArr[i].fn.call(objArr[i].obj)。これが、jQuery や Mootools、PrototypeJS のように優れた JS ライブラリが行う方法です。
  • 2 つ目の問題ですが、コールバック関数が例外をスローしてエラーが発生した場合はどうなりますか? 一部のブラウザーでは、ループの反復が停止するため、それ以上コールバック (関数) が呼び出されなくなります。ソリューションは、try catch ブロックを使用するか、私のお気に入りの方法を実行するかのいずれかで、複数にすることができます。コードが以下のようになるように使用setTimeoutします。JS はシングル スレッド ブラウザであるため、コールバック関数がキューに入れられ、エラーが発生した場合でも、残りの関数は影響を受けません。
    関数通知(objArr){
        for (var i in objArr){
            window.setTimeout(function(){ objArr[i].call(objArr[i].obj);}, 0);
        }
    }
  • それは間違いなく最適ではありませんが、最適なソリューションに近いため、改善するために多くのライブラリを調べてください(Google it)。イベント管理用のスタンドアロン PUB SUB ライブラリの 1 つを自分で作成しました。ここで確認してください。
于 2012-10-20T06:05:59.720 に答える
1

この記事を見てください

http://jqfaq.com/how-to-make-a-plain-vanilla-java-script-object-start-notifying-changes-to-its-properties/

http://jqfaq.com/how-to-get-notified-within-an-object-when-one-of-that-objects-property-changes/

この記事では、Object.defineProperty を使用してプロパティの変更を通知する方法を確認できます。

于 2012-10-20T06:11:44.960 に答える