Javascript 循环和闭包。For和Var
我发现了许多解释这个问题的主题,关于如何使用var修复下面的代码,比如这一个 或者这个 但我真的不明白为什么在使用var和let时它不起作用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 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个块范围?我认为这是迄今为止我找到的最好的解释。谢谢