1

可能重复:
循环内的 Javascript 闭包 - 简单的实际示例

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

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 模板客户端。这是一个粗略的演示,基本上完成了相同类型的事情(逻辑上),但我陷入了这个技术问题,它阻碍了我的进步。

谢谢

编辑

让我给出完整的问题。我不想让每个人都超载,但这些解决方案不起作用......

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)。我已经根据一些答案对其进行了更改,但它仍然无法正常工作。套接字在这里应该不是问题。问题显然是我生成成员时的前端逻辑,因为每个成员都反映了最后添加的成员。

解决了!见下文!(这不是关闭!!!)

4

4 回答 4

6

这被称为“闭包效应”:您的每个函数都知道它应该处理变量 named ,但在调用时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)运算符。

于 2012-12-11T18:35:29.020 回答
1

这应该可以解决问题:

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

注意:用于 IE8 的 ES5-shim

于 2012-12-11T18:32:24.530 回答
1

你有一个与闭包相关的问题 - 看看这个以获得好的文章。

于 2012-12-11T18:35:32.180 回答
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);});

效果很好。看起来它不喜欢循环遍历一个对象。哦,好吧,我猜是静态套接字声明!

于 2012-12-11T19:15:23.913 回答