for循环中的闭包/回调

时间:2011-11-16 20:34:30

标签: javascript for-loop closures

  

可能重复:
  Event handlers inside a Javascript loop - need a closure?

我一直试图让它工作一段时间,并决定只是问。

我有以下内容:

function doSomething(var1, var2) {
    dojo.xhrGet({
        url:"somUrl",
        content: {value1:var1,value2:var2},
        preventCache: true,
        handleAs:"json",
        load: function(response){
            for(var i in response.myObject) {
                var listItem = new dojox.mobile.ListItem({
                    label: response.myObject[i].name,
                    rightText: response.myObject[i].value,
                    clickable: true, 
                    onClick: function() {
                        customFunction(response.myObject[i]);
                        this.transitionTo("someScreen");
                    }   
                });
                myList.addChild(listItem);
            }               
        },
        error:function(e){alert(e);}
    });
}
doSomething(myVal1, myVal2);

customFunction(response.myObject[i]);行总是返回myObject arrray中的最后一个对象。

有人可以帮助我使用语法,这样我才能正常工作吗?我一直在阅读关于js闭包和回调但我无法让它工作。

由于

2 个答案:

答案 0 :(得分:3)

您需要一个额外的包装函数

onClick: (function(obj) {
    return function() {
        customFunction(obj);
        this.transitionTo("someScreen");
    };
})(response.myObject[i])

请参阅this answer获取解释:

  

JavaScript的范围是功能级别,而不是块级别和创建   闭包只意味着封闭的范围被添加到   封闭函数的词汇环境。

     

循环终止后,函数级变量i具有   值5 [注意: 或者,在这种情况下, response.myObject中的最后一个属性的名称],这就是内部函数'看到。

答案 1 :(得分:2)

您需要确保在for循环的每次迭代中闭包中包含i

[...]
  load: function(response){
        for(var i in response.myObject) {
            var listItem = new dojox.mobile.ListItem({
                label: response.myObject[i].name,
                rightText: response.myObject[i].value,
                clickable: true, 
                onClick: (function(inner) {
                    return function (clickEvent) {
                      customFunction(response.myObject[inner]);
                      this.transitionTo("someScreen");
                    }
                }(i))   
            });
            myList.addChild(listItem);
        }               
    }
 [...]