可能重复:
Javascript closure inside loops - simple practical example
我正在尝试做这样的事情:
var obj = function(){
var members = ['a','b','c','d','e'];
for(var i in members){
inst[i] = function(){
console.log(i);
}
}
};
但是当我这样做时:
var inst = new obj();
inst.a(); inst.b(); inst.c(); inst.d(); inst.e();
打印出5次!此外,我可能能够引用this
而不是使用我实例化对象的名称,但我根本无法使用它。这背后的逻辑是使用websockets来生成API模板客户端。这是一个粗略的演示,基本上是相同类型的东西(逻辑上),但我陷入了这个技术问题,它让我不能进步。
由于
修改
让我给出完整的问题。我不想让每个人都超负荷,但这些解决方案都不起作用......
var SocketClient = function(config){
//platform specific stuff
var self = this;
var count = 0;
var socket = io.connect(config.address+':'+config.port);
var members = [];
socket.on('method',function(data){
console.log(data.name);
KovarApp.client[data.name] = addLogicMember(data.name);
console.log(KovarApp.client[data.name]);
});
var addLogicMember = function(n){
return function(config){
var callback = null;
if(typeof config.callback !== 'undefined'){
var callback = config.callback;
delete config.callback;
}
call({
method: n,
data: config,
callback: callback
});
};
};
var call = function(config){
var c = count++;
var timer = null;
socket.on('reply_'+c,function(data){
if(typeof config.callback === 'function'){
if(timer != null){
timer.clearTimeout();
}
config.callback(data);
timer = setTimeout(function(){
socket.removeAllListeners('reply_'+c)
},10000);
}
});
config.data.handle = c; //make sure that the server has the handle for this function call
socket.emit(config.method,config.data);
};
};
服务器向客户端发出5个函数:login是第一个函数,getpatientinfo是最后一个函数。在服务器上,我将它设置为console.log每个回复。如果我调用任何函数,它就是console.log的getpatientinfo,因为它是它接收的字符串,这意味着在客户端上每个函数都引用最后一个接收到的字符串(getpatientinfo)。我根据一些答案改变了它,但它仍然没有用。套接字不应该是一个问题。在生成成员时,问题显然是我的前端逻辑,因为每个成员都反映了最后添加的成员。
解决了!见下文! (这不是关闭!!!)
答案 0 :(得分:6)
这称为“封闭效应”:您的每个函数都知道它应该处理名为i
的变量,但它将采用其当前值在被调用时。
要解决此问题,范围i
:
var makeMeAFunction = function(x) {
return function() { console.log(x); };
};
for(var i in members){
inst[i] = makeMeAFunction(i);
}
作为旁注,使用for...in
迭代数组通常是一个坏主意:使用forEach
或者,如果您只需要支持IE8,请使用传统的for(init; check; step)
运算符。< / p>
答案 1 :(得分:1)
这应该可以解决问题:
function Cn () {
var self = this;
[ 'a','b','c','d','e' ].forEach(function ( name, i ) {
self[ name ] = function () {
console.log( i );
};
});
}
答案 2 :(得分:1)
你有一个与闭包相关的问题 - 看看this是否有好的记录。
答案 3 :(得分:0)
发现问题,男孩我觉得自己像个笨蛋!
问题是服务器端。我这样做了:
for(var i in functions){
socket.on(i,function(data){functions[i](data,socket,mysql)}); //create socket listeners
}
当我把它更改为:
socket.on('login',function(data){functions.login(data,socket,mysql);});
socket.on('logout',function(data){functions.logout(data,socket,mysql);});
socket.on('getVisitInfo',function(data){functions.getVisitInfo(data,socket,mysql);});
效果很好。看起来它不喜欢在对象中循环。哦,我猜它是静态套接字声明!