3

我正在尝试使用循环中的函数创建数组。但我认为不要对封装有所了解。

例如,此代码返回“y y”。现场演示

HTML

<div id="result"></div>

Javascript

var json = {
            '1':'x',
            '2':'y'
           };
var my_array = [];
var div = document.getElementById('result');

for (var key in json) {
    my_array.push(function() { 
        div.innerHTML = div.innerHTML + ' ' + json[key];
    });
};

var length = my_array.length;

for (var i = 0; i < length; i++) {
  my_function = my_array[i];
  my_function();
}

我应该怎么做才能得到“x y”?

Tnx 很多。

4

1 回答 1

8

这是由于闭包在 JavaScript 中的工作方式。

你想要这样的东西:

for (var key in json) {
    (function(key) {
        my_array.push(function() { 
            div.innerHTML = div.innerHTML + ' ' + json[key];
        });
    })(key);
}

在 JavaScript 中,闭包或匿名函数在词法上绑定到定义它们的范围。这意味着它们可以访问在定义闭包的范围内定义的所有变量

所以在你的原始代码中,你有key,它最初指向1. 在你的函数中,你有json[key],它最初是json[1],它是x。然后,当循环进入下一次迭代时,您已key设置为2. 但问题是key第一个函数实例和第二个函数实例都指向同一个位置。因此,当您最终评估函数时,它们将使用执行时的key任何值。在执行时,设置为,因为这是循环结束时的最后一个值。key2key

要解决此问题,您必须使用匿名的自调用函数来引入新范围。通过使用这种模式,您故意引入了一个的作用域,以便key在这个新作用域中具有自己的位置,并且key与外部作用域中的不同。

查看更新的小提琴

于 2013-07-11T20:53:57.250 回答