我正在尝试在 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"
但是,订阅一个作为对象方法的函数是行不通的:
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
我也试过使用 apply(假设数据是一个数组):
PubSub.publish=function(topic,data){
...
this.subscriptions[topic][i].apply(this,data);
...
}
它也不起作用,尽管我相信这不是同一个问题:我认为 apply 传递的 this
对象覆盖了 a 的
,因此 this
对象a.i
尝试设置 PubSub.a
而不是 a.a
...
最佳答案
当您将 a.i
传递给 PubSub.subscribe
时,您已经从 a
中“分离”了 i
函数>,它的调用上下文。要么使用匿名函数来维护绑定(bind):
PubSub.subscribe("test", function (x) { a.i(x); });
或使用 Function.bind
每当调用 i
时将 a
保留为 this
:
PubSub.subscribe("test", a.i.bind(a));
注意Function.bind
并非在所有浏览器中均受支持,因此您需要 use the shim .
关于Javascript 发布/订阅实现适用于函数,但不适用于对象的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10107340/