dynamic添加成员到对象

可能重复:
内部循环的Javascriptclosures – 一个简单的实例

我正在尝试做这样的事情:

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(); 

它打印出e 5次! 另外,我可能会引用this而不是使用我实例化对象的名称,但是我无法完全解决这个问题。 这背后的逻辑是使用websockets来生成一个API模板客户端。 这是一个粗略的演示,基本上是相同types的东西(逻辑上),但我陷入了这个技术问题,并阻止我进步。

谢谢

编辑

让我给完整的问题。 我不想重载每个人,但这些解决scheme不工作…

 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是因为它是它接收到的string,这意味着在客户端上,每个函数都引用最后接收到的string(getpatientinfo)。 我已经根据一些答案改变了它,但它仍然不起作用。 套接字在这里不应该是个问题。 这个问题显然是我在生成成员时的前端逻辑,因为每个成员都反映了最后添加的成员。

解决了! 见下文! (这不closures!!!)

这被称为“闭包效应”:你的每一个函数都知道它应该处理名为ivariables,但是在被调用时会取其当前的值。

为了解决这个问题,范围i也是:

 var makeMeAFunction = function(x) { return function() { console.log(x); }; }; for(var i in members){ inst[i] = makeMeAFunction(i); } 

作为一个旁注,迭代Array的for...in :use forEach通常是一个糟糕的主意,或者,如果你只是需要支持IE8,可以使用传统for(init; check; step)运算符。

这应该做的伎俩:

 function Cn () { var self = this; [ 'a','b','c','d','e' ].forEach(function ( name, i ) { self[ name ] = function () { console.log( i ); }; }); } 

注意: IE8的ES5-shim

你有一个closures相关的问题 – 看看这个很好的写作。

发现这个问题,男孩我觉得像一个娃娃!

问题是服务器端。 我正在这样做:

  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);}); 

它运作良好。 它看起来像不喜欢循环通过一个对象。 哦,我猜是静态套接字声明!