具有javascript函数的范围

时间:2013-10-30 18:22:37

标签: javascript scope

我试图将我传递给inputItems [i] .on所以我可以将它设置为执行特定任务(由createSelectedInputItem(i)定义),如何将变量i传递给function(){。 .operation here}?

for(var i=0; i< 6; i++){
    console.log("setting mouse event for : " + i);

    // Bring in all the input items
    inputItems[i].on('click', function() {

      console.log("i is still:" + i );
      input.tween.reverse();
      console.log("pressed" + i);
      createSelectedInputItem(i);

      for(var j=0; j< 6; j++){
        inputItems[j].tween.reverse();
      } 
    });
  }

LOG

//加载页面时

setting mouse event for : 0

setting mouse event for : 1 

setting mouse event for : 2 

setting mouse event for : 3 

setting mouse event for : 4 

setting mouse event for : 5 

//按下其中一个inputItems

我还是:6

pressed6 

这甚至假设存在

2 个答案:

答案 0 :(得分:0)

inputItems[i].on('click', function() {
    // By the time this runs, any variable outside its scope may change,
    // which in this case is 'i' which runs in a loop.
});

你应该像这样包装i

(function(i) {
    inputItems[i].on('click', function() {
        // Now i is an argument to the wrapping closure
        console.log(i);
    });
})(i);

答案 1 :(得分:0)

您面临的问题是闭包,这是Javascript范围的一个稍微不直观的方面。

考虑一下你有多少变量。变量i存在多少次?答案是“有定义i的范围的次数”。在这种情况下,这意味着只有一个变量i,在整个代码中都会引用它。

您使用i进行循环:

for(var i=0; i< 6; i++){

此循环完成后(在您点击之前发生),i6。它永远不会再改变,它永远不会引用任何其他数字。

因此点击处理程序触发,这行代码运行:

console.log("i is still:" + i );

i是同一个变量,因此它将是值6

解决这个问题的方法是为循环的每次迭代引入一个新变量。

for (var i = 0; i < 6; i++) {
    (function (innerI) { // create a function with an argument called innerI
        console.log("setting mouse event for : " + i);

        // Bring in all the input items
        inputItems[innerI].on('click', function () {
            console.log("i is still:" + i);
            console.log("innerI is: " + innerI);
            input.tween.reverse();
            console.log("pressed" + innerI);
            createSelectedInputItem(i);

            for (var j = 0; j < 6; j++) {
                inputItems[j].tween.reverse();
            }
        });
    }(i)); // invoke the function with i as the argument
}

在这段代码中,我们创建了一个匿名函数。该函数采用一个参数innerI。然后我们立即调用该函数,并传递i作为参数。这会创建一个新范围和一个新变量,因此在循环结束时i++发生时不会更改。