我尝试在循环中创建具有函数的数组。但我认为没有关于封装的东西。
例如,此代码返回“y y”。 Live demo
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很多。
答案 0 :(得分: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
具有的任何值。在执行时,key
设置为2
,因为这是循环结束时key
的最后一个值。
要解决此问题,您必须使用匿名的自调用函数来引入新范围。通过使用此模式,您有意引入 new 范围,以使此新范围中的key
具有自己的位置,并且与外部范围中的key
不同。