1

我确信有一个非常简单的解决方案,但我无法理解它。我正在尝试在 for 循环中创建对象数组,如下所示:

for(var i = 0; i < 100; i++) {
    foos[i] = new Foo(i*10);
    bars[i] = someObject.createBar({
         x : 0,
         y : 0,
         foobar = function() {
              foo[i].a = true;
         }
    });
}

当尝试运行它时,我得到“无法设置未定义的属性 a”,foos 和 bar 在代码的前面都被声明为全局变量。

如果我将 foos 创建为 foos[0] 并通过 bar[0] 访问,它工作正常。我怀疑这与函数级别范围有关,但据我所知,数组应该可以在全局对象上访问......

4

4 回答 4

3

您需要“锚定” 的值i。去做这个...

for(var i=0; i<100; i++) {
    (function(i) {
        // now do stuff with i
    })(i);
}
于 2012-06-18T19:12:46.467 回答
0

试试这个:

for(var i = 0; i < 100; i++) { 
    foos.push( new Foo(i*10) ); 
    bars.push( someObject.createBar({ 
         x : 0, 
         y : 0, 
         foobar = function() { 
              foo[i].a = true; 
         } 
    }) ); 
} 
于 2012-06-18T19:11:13.470 回答
0

i 在执行 foobar 时的值是循环结束时的值(100)。因为循环块是一个闭包。

你最好存储你想要的值。例如 :

for(var i = 0; i < 100; i++) {
    foos[i] = new Foo(i*10);
    bars[i] = someObject.createBar({
         x : 0,
         y : 0,
         i : i,
         foobar: function() {
              foos[i].a = true;
         }
    });
}

或者在循环中使用中间闭包来包含 i :

for(var i = 0; i < 100; i++) {
    (function(i){
        foos[i] = new Foo(i*10);
        bars[i] = someObject.createBar({
             x : 0,
             y : 0,
             foobar: function() {
              foos[i].a = true;
             }
        });
    })(i);
}

第一个解决方案更明确,第二个可能现在更常见。

于 2012-06-18T19:12:14.130 回答
0

您不能设置未定义的值“a”,因为“foo[i]”未定义。你从来没有定义过 foo[i]。你的意思是 foos[i],也许吧?

此外,正如其他人所说,您的函数 foobar 将为您创建的每个对象使用相同的 i 值。您应该使用 i 创建一个新的闭包,这将允许您定义一个局部变量 i,该变量对于每个内部函数都可能不同,如下所示:

for(var i=0; i<100; i++) {
   (function(i) {
      // now do stuff with i
   })(i);
}
于 2012-06-18T19:17:26.640 回答