我知道这个问题与JS范围有关,我已经搜索过,但无法让other stackoverflow questions的解决方案起作用。
我有这个程序
function write(x, y) {
console.log(x);
console.log(y);
}
var data = {
"property": {
"1": {
"values": [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
},
"2": {
"values": [[11, 12], [13, 14], [15, 16], [17, 18], [19, 20]]
}
}
}
var delay = 1000;
for (var x in data.property) {
for (var i = 0; i < data.property[x].values.length; i++) {
var one = data.property[x].values[i][0];
var two = data.property[x].values[i][1];
setTimeout(function() {
write(one, two);
}, delay);
delay += 1000;
}
}
从对象读取数据并在对象和其中的数组上循环。我希望它相隔一秒打印数组值,但它总是打印最后一次迭代的值。我已尝试使用其他问题中建议的闭包,但无法使其工作。
答案 0 :(得分:1)
您可以应用own research并使用以下方法。
for (var i = 0; i < data.property[x].values.length; i++) {
(function (one, two) {
setTimeout(function() {
write(one, two);
}, delay);
})(data.property[x].values[i][0], data.property[x].values[i][1]);
delay += 1000;
}
工作jsfiddle:http://jsfiddle.net/0z525bhf/1/
答案 1 :(得分:1)
在setTimeout
的特定情况下,您甚至不需要关闭。您可以将变量传递给超时函数,如下所示:
for (var x in data.property) {
for (var i = 0; i < data.property[x].values.length; i++) {
var one = data.property[x].values[i][0];
var two = data.property[x].values[i][1];
setTimeout(function(one, two) {
write(one, two);
}, delay, one, two);
delay += 1000;
}
}
答案 2 :(得分:0)
这是词汇闭包的问题:传递给setTimeout
的函数会关闭在迭代期间被修改的变量one
和two
。这就是为什么你应该永远不要在for循环体中声明一个函数。
使用功能循环将解决它:
var delay = 1000;
for (var x in data.property) {
data.property.value[x].forEach(function (tuple) {
var one = tuple[0], two = tuple[1];
setTimeout(function() {
write(one, two);
}, delay);
delay += 1000;
});
}