繁体   English   中英

循环和闭包。 For和Var

[英]Loops and closures. For and Var

我找到了许多主题来解释此问题,这些主题涉及如何使用var修复以下代码,例如http://conceptf1.blogspot.com/2013/11/javascript-closures.html循环内的一个JavaScript闭包–简单的实际例子

但是我真的不明白为什么使用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

我真的不知道...

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

在第一for循环, function仅仅是分配给func[i]与最终值3但不执行3次。 如果在first loop执行该函数,则将获得预期的输出,例如:

 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. }; funcs[i](); // execution of func } 

因此,重要的是函数在哪个上下文中执行。

现在,在您的代码中首次执行funcs[j]()时, i的值已经是3 如果要记录增量值,则必须将其作为参数传递,如下所示:

 var funcs = []; for (var i = 0; i < 3; i++) { // let's create 3 functions funcs[i] = function(j) { // and store them in funcs console.log("My value: " + j); // each should log its value. }; } for (var j = 0; j < 3; j++) { funcs[j](j); // and now let's run each one to see } 

因为var是函数作用域的(也就是说,具有周围函数的作用域),而letconst是块作用域的-因此在每个块中都有自己的值( if - else -block或每次迭代视情况而定)。 未在块外部定义块作用域变量。 作用域变量将一直保留到函数结束。

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

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

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); 
  };
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM