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);

我希望您对这两条注释行有想法(如果它实际上会像预期的那样工作)以及是否可能有更直接的方式通过调用对象的方法来通知对象。(例如,我注意到一些实现将函数名作为字符串传递,而不是对函数的引用,而不是这种方式。)

谢谢

4

2 回答 2

2

好的,首先有多个问题,让我们一一讨论:

  • objArr[i].obj.fn();不会做你所期望的。它将查找并调用 fn 方法,但是您期待myMethod从 obj 调用。要解决此问题,您有多种选择。要么使用apply,要么call。所以你的代码看起来像objArr[i].fn.call(objArr[i].obj). 这就是像 jQuery、Mootools 或 PrototypeJS 那样优秀的 JS 库是如何做到的。
  • 第二个问题,如果回调函数抛出异常并有错误怎么办?在某些浏览器中,循环将停止迭代,因此不会调用进一步的回调(函数)。解决方案可以再次使用多个,要么使用 try catch 块,要么做我最喜欢的方法。使用setTimeout这样您的代码将如下所示,由于 JS 是单线程浏览器,因此会将回调函数排队,即使出现错误,其余的也不会受到影响。
    函数通知(objArr){
        for(objArr 中的变量 i){
            window.setTimeout(function(){ objArr[i].call(objArr[i].obj);}, 0);
        }
    }
  • 它绝对不是最佳但接近最佳解决方案,因此请查看周围的许多库(Google it)以改进它。我自己为事件管理编写了一个这样的独立 PUB SUB 库,在这里查看
于 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 回答