Javascript 发布/订阅实现适用于函数,但不适用于对象的方法

标签 javascript function object methods publish-subscribe

我正在尝试在 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/

相关文章:

Java 对象内存占用 - Visualvm 和 java.sizeOf 测量

java - 尝试对对象数组进行排序时出现 NullPointerException

javascript - 空链 anchor

JavaScript onmouseleave 和 onmouseenter 在 Firefox 和 IE9 中工作,但在 Chrome 中不起作用?

r - 曲线错误(): 'expr' did not evaluate to an object of length 'n'

r - 使用R编写一个读取文件的函数

javascript - 如何在javascript中创建带有连接的变量?

javascript - 如何将表格附加到DIV

javascript - 将 req.query ['name' ] 的值保存到 Node.jS 中的变量中?

function - 支持 Python 中的逻辑门模拟程序