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

Javascript 为什么在for循环中声明的变量会在每次迭代中更新而不是重新创建?,javascript,loops,asynchronous,closures,Javascript,Loops,Asynchronous,Closures,下面是一个代码: var data = [ 'data1', 'data2', 'data3' ]; for (var i = 0; i < data.length; i++) { var x = data[i]; setTimeout(function() { console.log(x); }, i * 100); } 更新相同的变量,而不是重新创建它 有人能解释一下这种行为吗?使用var声明的变量具有函数作用域。这意味着整个函数中只有一个具

下面是一个代码:

var data = [ 'data1', 'data2', 'data3' ];

for (var i = 0; i < data.length; i++) {
    var x = data[i];
    setTimeout(function() {
        console.log(x);
    }, i * 100);
}
更新相同的变量,而不是重新创建它


有人能解释一下这种行为吗?

使用
var
声明的变量具有函数作用域。这意味着整个函数中只有一个具有该名称的变量。无论
var
声明位于何处。函数声明隐式地“提升”到函数的顶部,是整个函数可用的单个变量

您的代码与此等效,这说明了为什么所有
setTimeout()
调用只共享一个
x
实例:

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);
}
在最新的ES6中,可以使用
let
声明变量,然后它们将具有您想要的块范围。因此,在最新的浏览器或node.js中,您可以使用
let
,它将具有所需的块范围:

var data = [ 'data1', 'data2', 'data3' ];

for (var i = 0; i < data.length; i++) {
    let x = data[i];
    setTimeout(function() {
        console.log(x);
    }, i * 100);
}
var data=['data1','data2','data3'];
对于(变量i=0;i
是。但是变量x是在循环内部创建的。它不是在外部作用域中创建的,因此循环可以更改它。这是否意味着,在循环内部和外部定义x变量没有区别?无论如何,它将属于外部作用域?@rhinomibreat-不,Javascript不是这样工作的。无论
var
定义位于何处,都会在函数顶部创建变量。Javascript将所有
var
定义“提升”到函数顶部。变量仅在
for
循环中分配。它是在函数的顶部创建的。请参阅我的第一个代码块,了解Javascript解释中真正发生的事情。如果你想了解更多关于“Javascript变量提升”的信息,可以在谷歌上搜索“Javascript变量提升”。是的,我对提升是什么以及它是如何工作的有一个概念。问题在于,我认为在循环中声明的变量只在循环中可用,并且在每次迭代中都会重新创建。感谢您的回答,特别是“等效”代码段。现在有道理了。
var data = [ 'data1', 'data2', 'data3' ];

for (var i = 0; i < data.length; i++) {
    (function(x) {
        setTimeout(function() {
            console.log(x);
        }, i * 100);
     )}(data[i]);
}
var data = [ 'data1', 'data2', 'data3' ];

for (var i = 0; i < data.length; i++) {
    let x = data[i];
    setTimeout(function() {
        console.log(x);
    }, i * 100);
}