Javascript 循环和闭包。For和Var

Javascript 循环和闭包。For和Var,javascript,loops,closures,var,let,Javascript,Loops,Closures,Var,Let,我发现了许多解释这个问题的主题,关于如何使用var修复下面的代码,比如这一个 或者这个 但我真的不明白为什么在使用var和let时它不起作用 var funcs = []; for (var i = 0; i < 3; i++) { // let's create 3 functions funcs[i] = function() { // and store them in funcs console.log("My v

我发现了许多解释这个问题的主题,关于如何使用var修复下面的代码,比如这一个 或者这个

但我真的不明白为什么在使用var和let时它不起作用

var funcs = [];        
for (var i = 0; i < 3; i++) {        //  let's create 3 functions
  funcs[i] = function() {            //  and store them in funcs
    console.log("My value: " + i);   //  each should log its value.
  };
}
for (var j = 0; j < 3; j++) {
  funcs[j]();                        //  and now let's run each one to see
}
// outputs 3 3 3
var funcs=[];
对于(var i=0;i<3;i++){//让我们创建3个函数
funcs[i]=function(){//并将它们存储在funcs中
log(“我的值:+i);//每个都应该记录其值。
};
}
对于(var j=0;j<3;j++){
funcs[j]();//现在让我们运行每个
}
//产出3

我真的不知道…

因为
var
是函数作用域(也就是说,拥有周围函数的作用域),而
let
&
const
是块作用域-因此在每个块中都有自己的值(无论是
if
-还是
else
-块还是循环的每个迭代,就像您的情况一样)。块作用域变量未在块外部定义。函数作用域变量一直保留到函数结束

您的
i
变量是函数作用域,这意味着一旦您的循环完成,它仍然存在于第一个循环之外&值为
3
。因此,一旦您调用了数组函数,它就会从上层作用域(即
3
)获取
i
,并将其输出。例如,如果您使用了
let
,那么每次迭代都会得到一个新的绑定,
i
的值将保留初始声明值

编辑: 因此,为了输出顺序值,您需要将
var
替换为
let

for (let i = 0; i < 3; i++) {
  funcs[i] = function() {
    // now `i` is bound to the scope & keeps its initial value
    console.log("My value: " + i); 
  };
}
for(设i=0;i<3;i++){
funcs[i]=函数(){
//现在'i'绑定到范围并保持其初始值
console.log(“我的值:+i”);
};
}

let
不同,
var
被提升到循环范围之外。事实上,您的
i
变量将始终等于最后一次迭代(在您的示例中为3)
let
没有这个问题,因为它没有被提升。

ES6的let
是块作用域,这意味着它在
{}
内部有自己的作用域,就像许多其他传统语言一样。但与此相反,
var
是代码中的全局变量

在循环的第一个
中,
函数
仅分配给
func[i]
3次,最终值为3,但未执行。如果在第一个
循环中执行该函数,您将获得预期的输出,如下所示:

var funcs=[];
对于(var i=0;i<3;i++){//让我们创建3个函数
funcs[i]=function(){//并将它们存储在funcs中
log(“我的值:+i);//每个都应该记录其值。
};
func[i]();//func的执行

}
您的意思是“使用var时不工作,使用let时工作”?可能的重复我检查了所有其他重复项,但我无法理解它们,只有下面的答案帮助我理解了这个问题。您能在我的答案中添加重写的代码,以便我能够轻松理解发生了什么?它是这样的:var i=0;对于(i;i<3;i++)而言?你能写下我使用var和let时范围开始和结束的时间吗?我知道如何使它工作,所有其他帖子和主题都给了我答案,但我真的不明白为什么使用var的初始解决方案不起作用。。。也许还有其他一些我能理解的代码示例?@Marek,如果你的问题是“但我真的不明白为什么var的初始解决方案不起作用”,那么你应该这么说,你不应该把
let
放在那里,因为这会让你的问题变得混乱,我邀请你编辑你的帖子,以反映你真正想知道的东西。我想我现在开始理解了。所以这行代码->console.log(“我的值:+i”);在使用var时,是否会使用全局i(3)值?如果我使用let,每次迭代都会为函数定义保留不同的I值?所以基本上,3次迭代将“生成”3个块范围?我认为这是迄今为止我找到的最好的解释。谢谢