0

我在获取显示以下内容的“名称”值时遇到问题:

   for (var name in array) {
        var hoverIn = function() {
                  alert(name);
        };

        var hoverOut = function() {
        };

        thing.hover(hoverIn, hoverOut);

   }

我得到的是一个带有最后一个 name 值的警报窗口。显然我做错了什么,我怀疑这是一个简单的修复。任何人都可以帮忙吗?

谢谢。

4

4 回答 4

7

这是闭包问题,name在迭代是最后一个name之后array,并且在迭代发生时不会立即执行悬停回调,因此当实际执行悬停函数时,name将始终是最后一个array

您需要使用 IEFE(立即执行的函数表达式):

   for (var name in array) {
        // pass in name to the anonymous function, and immediately
        // executes it to retain name when the particular iteration happens
        var hoverIn = (function(name) {
             return function() {
                  alert(name);
             }
        })(name); // if you notice, the pattern is (function(name) {})(name) 
                  // the first () creates an anonymous function, the (name) 
                  // executes it, effectively passing name to the anon fn

        var hoverOut = (function(name) {
            // same pattern if you need to re-use name inside here, otherwise just
            // function() { } should suffice
        })(name);

        thing.hover(hoverIn, hoverOut);

   }

为了避免重复(function() { })()(老实说看着很累),您还可以,正如@pimvdb 指出的那样,将整个主体包裹在一个闭包中:

   for (var name in array) {
        (function(name) {
           var hoverIn = function() {
               alert(name);
           }

           var hoverOut = function() {
           }

           thing.hover(hoverIn, hoverOut);
        })(name); // closure of for loop body

   }
于 2012-08-17T09:43:53.870 回答
0

在循环中添加一个变量

var thisName = name;

然后在你的函数中使用它

alert(thisName);
于 2012-08-17T09:43:34.563 回答
0

你有两种方法来处理这个问题。

首先要知道的是作用域只发生在函数级别,而不是在 javascript 的循环中。如果您从外部源在函数中设置变量并且不立即执行它,则该变量将在循环过程中更改。

您可以通过关闭其他变量来解决此问题:

var names = ["john","paul","george","ringo"];
var store = {};

//this function receives the data as a parameter
//so it will be a safe copy.

function createFunc(name){
     //just return a function that will alert the name.
    return function(){
       alert(name);
    }
}
for (var i in names) {

        var hoverIn = createFunc(names[i]);

        store[names[i]]=hoverIn;

}
store["john"]();

另一种方法是创建一个在循环中立即执行的匿名函数:

var names = ["john","paul","george","ringo"];
var store = {};

for (var i in names) {
   //the function receives the i as a parameter
   //and executes, so n is a safe copy of i
  (function(n){

    var hoverIn = function(){
        alert(names[n]);
    }

    store[names[n]]=hoverIn;

  })(i);

}
store["john"]();

一切都是与关闭有关的问题。查看维基百科了解更多信息。

于 2012-08-17T10:03:29.473 回答
-2

您应该创建闭包:

 for (var name in array) {
        var hoverIn = (function() {
              return function() {
                  alert(name);
              };
        }());

        var hoverOut = function() {
        };

        thing.hover(hoverIn, hoverOut);
   }
于 2012-08-17T09:43:22.953 回答