Javascript 使用for循环添加socket.on方法的socket.io

Javascript 使用for循环添加socket.on方法的socket.io,javascript,node.js,sockets,socket.io,Javascript,Node.js,Sockets,Socket.io,假定 这在下面是可能的,并且允许我发出“test”和“update”,并且将调用“test”和“update” socketMethods:{ update:function(data){ this.emit("test", data); console.log("socket.update"); }, test:function(data){ this.emit("test", data); console

假定

这在下面是可能的,并且允许我发出“test”和“update”,并且将调用“test”和“update”

socketMethods:{
    update:function(data){
        this.emit("test", data);
        console.log("socket.update");
    },
    test:function(data){
        this.emit("test", data);
        console.log("socket.test");
    }
}
下面这些是不可能的。。。如果我发出“test”或“update”,则每个函数都将调用“test”。如果使用FOR循环,所有方法都将成为调用的“最后”方法

也就是说:如果我切换了update和test,那么在socketMethods对象中test是第一个,update是第二个。无论我是要求“测试”还是“更新”,都将始终调用“更新”

for(输入dummy.socketMethods){
socket.on(钥匙、功能(数据){
summy.socketMethods[key].call(套接字,数据);
});
}
var方法=[“测试”,“更新”];
while(methods.length!==0){
var method=methods.pop();
console.log(方法);
socket.on(方法、函数(数据){
dummy.socketMethods[method].call(套接字,数据);
});
}
var方法=[“测试”,“更新”];
对于(var i=0;i
提示:使用“i”的for循环有两个console.log。第二个console.log返回“2”


为什么会发生这种情况?我怎样才能使用for循环来附加socketMethods呢?

您犯了一个常见的错误,即假设一个闭包在创建外部函数的变量时“捕获”了它的值。没有。它“捕获”了对外部函数变量的引用,其值将是执行闭包时外部变量的值。如果在循环中创建闭包,则该值将是循环结束时的值

解决这个问题的方法是创建一个使用外部变量值作为参数的“封闭”闭包。一种方法是创建一个生成闭包的助手函数。在第一个示例中,您可以

for(key in dummy.socketMethods){
    socket.on(key, function(data){
        dummy.socketMethods[key].call(socket, data);
    });
}



var methods = ["test", "update"];
while(methods.length !== 0){
    var method = methods.pop();
    console.log(method);
    socket.on(method, function(data){
        dummy.socketMethods[method].call(socket, data);
    });
}



var methods = ["test", "update"];
for(var i = 0; i < methods.length; i++){
    console.log(i);
    socket.on(methods[i], function(data){
        console.log(i);
        dummy.socketMethods[methods[i]].call(socket, data);
    });
}
现在在每个闭包中,
key
将是一个新创建的变量(闭包之间不同),设置为适当的值


也可以使用即时函数调用(有些人称之为“自动执行函数”)来更简洁地完成同样的事情,但可读性稍差。

您犯了一个常见的错误,即假设闭包“捕获”外部函数变量在创建时的值。没有。它“捕获”了对外部函数变量的引用,其值将是执行闭包时外部变量的值。如果在循环中创建闭包,则该值将是循环结束时的值

解决这个问题的方法是创建一个使用外部变量值作为参数的“封闭”闭包。一种方法是创建一个生成闭包的助手函数。在第一个示例中,您可以

for(key in dummy.socketMethods){
    socket.on(key, function(data){
        dummy.socketMethods[key].call(socket, data);
    });
}



var methods = ["test", "update"];
while(methods.length !== 0){
    var method = methods.pop();
    console.log(method);
    socket.on(method, function(data){
        dummy.socketMethods[method].call(socket, data);
    });
}



var methods = ["test", "update"];
for(var i = 0; i < methods.length; i++){
    console.log(i);
    socket.on(methods[i], function(data){
        console.log(i);
        dummy.socketMethods[methods[i]].call(socket, data);
    });
}
现在在每个闭包中,
key
将是一个新创建的变量(闭包之间不同),设置为适当的值


也可以使用即时函数调用(有些人称之为“自动执行函数”)来更简洁地完成同样的事情,但可读性稍差。

我甚至无法开始表达由于这篇文章,我将对闭包进行多少研究。这很有效——即时——甚至不需要运行两次。我想我甚至不能——开始——表达我因为这篇文章要研究闭包的程度。它立即起作用,甚至不需要运行两次。
function makeOn(key) {
  return function(data) {
    dummy.socketMethods[key].call(socket, data);
  }
}

for(key in dummy.socketMethods){
  socket.on(key, makeOn(key));
}