gpt4 book ai didi

javascript - 为什么在 for 循环中声明的变量会更新而不是在每次迭代时重新创建?

转载 作者:行者123 更新时间:2023-12-02 15:19:26 24 4
gpt4 key购买 nike

这是一个代码:

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com