2012-04-11 50 views
1

我想實現一個簡單的發佈/訂閱對象在JavaScript中,這是我的代碼:的Javascript的pub/sub實現工程的功能,而不是對象的方法

var PubSub=new function(){ 
    this.subscriptions=[]; 
    this.subscribe=function(topic,callback){ 
     if(!this.subscriptions[topic]){ 
      this.subscriptions[topic]=[]; 
     } 
     this.subscriptions[topic].push(callback); 
    } 
    this.unsubscribe=function(topic,callback){ 
     if(this.subscriptions[topic]){ 
      for(var i=this.subscriptions[topic].length-1;i>=0;i--){ 
       if(this.subscriptions[topic][i]==callback){ 
        this.subscriptions[topic].splice(i,1); 
       } 
      } 
     } 
    } 
    this.publish=function(topic,data){ 
     if(this.subscriptions[topic]){ 
      for(var i=this.subscriptions[topic].length-1;i>=0;i--){ 
       this.subscriptions[topic][i](data); 
      } 
     } 
    } 
} 

現在,訂閱一個簡單的函數,然後發佈一些東西的偉大工程:

PubSub.subscribe("test",print); //print: shell function 
PubSub.publish("test","hello"); //print outputs "hello" 

不過,訂閱功能,這是一個對象的方法doen't工作:

var a=new function(){ 
    this.c=0; 
    this.i=function(x){ 
     this.c+=x; 
    } 
} 
PubSub.subscribe("test",a.i); 
PubSub.publish("test",17); 
a.c; //is still 0 

我使用應用(假設數據是一個數組)也試過:

PubSub.publish=function(topic,data){ 
    ... 
     this.subscriptions[topic][i].apply(this,data); 
    ... 
} 

它不工作,要麼,但我認爲這是不一樣的問題:我想通過應用覆蓋了this對象傳遞的this對象的a,因此a.i嘗試設置PubSub.a而不是a.a ...

+0

還應該注意的是:this.subscriptions = [];應該改爲this.subscriptions = {};根據你如何使用它。 – cweston 2015-02-26 21:36:56

回答

2

當你傳遞給a.iPubSub.subscribe,你已經「分離」的ia功能,它的調用上下文。既可以使用匿名函數保持綁定:

PubSub.subscribe("test", function (x) { a.i(x); }); 

或使用Function.bind保存a作爲this每當i被稱爲:

PubSub.subscribe("test", a.i.bind(a)); 

注: Function.bind在所有瀏覽器中都不受支持,因此您需要use the shim

+1

好的謝謝,我明白爲什麼我的例子沒有工作!當我使用匿名函數時,'unsubscribe'不再工作,但首先聲明函數,所以它有一個名字,然後將它傳遞給'subscribe'來解決這個問題。 – Alex 2012-04-11 14:19:31

相關問題