这是一个代码:
var data = [ 'data1', 'data2', 'data3' ];
for (var i = 0; i < data.length; i++) {
var x = data[i];
setTimeout(function() {
console.log(x);
}, i * 100);
}
输出是“data3”的 3 倍。我的问题是为什么?
我知道所有 3 个日志方法将在循环完成后调用,并且变量 i 将等于 3,但是!
我在循环内定义 x 变量。我期望在每次循环迭代时在本地重新创建该变量,以便在调用每个 console.log(x) 方法时它们引用存储在内存中的 3 个不同变量。
但它看起来像代码:
var x = data[i];
更新相同的变量而不是重新创建它。
有人可以解释一下这种行为吗?
最佳答案
使用var
声明的变量具有函数作用域。这意味着整个函数中只有一个具有该名称的变量。 var
声明在哪里并不重要。函数声明隐式“提升”到函数顶部,并且是整个函数可用的单个变量。
您的代码与此等效,这说明了为什么只有一个 x
实例被所有 setTimeout()
调用共享:
var data = [ 'data1', 'data2', 'data3' ];
var x;
for (var i = 0; i < data.length; i++) {
x = data[i];
setTimeout(function() {
console.log(x);
}, i * 100);
}
您可以通过在适当的位置引入一个函数来解决您的问题,以便在其自己的函数范围内唯一捕获 x
的每个值:
var data = [ 'data1', 'data2', 'data3' ];
for (var i = 0; i < data.length; i++) {
(function(x) {
setTimeout(function() {
console.log(x);
}, i * 100);
)}(data[i]);
}
在最新的 ES6 中,可以使用 let
声明变量,然后它们将具有您想要的 block 作用域。因此,在最新的浏览器或 Node.js 中,您可以使用 let
,它将具有所需的 block 范围:
var data = [ 'data1', 'data2', 'data3' ];
for (var i = 0; i < data.length; i++) {
let x = data[i];
setTimeout(function() {
console.log(x);
}, i * 100);
}
关于javascript - 为什么在 for 循环中声明的变量会更新而不是在每次迭代时重新创建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34191043/