循环和关闭。 对于和VAR(Loops and closures. For and Var)

2019-10-29 04:37发布

我发现很多题目解释这个问题,我如何能利用VAR,像这样的解决下面的代码http://conceptf1.blogspot.com/2013/11/javascript-closures.html或这一个JavaScript的闭包内环路-简单实用的例子 。

但我真的不明白为什么它不使用VAR时以及使用时让工作工作。

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

我真的不知道......

Answer 1:

ES6's let是阻止范围,这意味着它有它自己的内部范围{}像许多其他的传统语言。 但相比之下var是代码中的全局变量。

在第一for循环, function仅仅是分配给func[i]与最终值3但不执行3次。 如果执行第一里面的功能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 } 



Answer 2:

不同于以letvar是循环范围之内悬挂。 其实,你i变量将始终等于上一次迭代(在你的例子是3)。 let的事业就没有悬挂不存在这个问题。



Answer 3:

因为var是函数作用域的(即,具有周围函数的范围),而letconst是块作用域-因此具有的每个块内它们自己的值(可以是if -或else嵌段或的每次迭代环路你的情况)。 块范围的变量不是外块定义。 功能范围的变量留到函数结束。

i的变量是功能范围的,这意味着一旦你的循环完成后,它仍然是目前的第一环外与具有值3 。 所以一旦你打电话给你的阵列功能,它需要i从上范围(这是3 )输出。 如果使用let ,例如,你会得到每个迭代与您的新鲜结合i的价值会保持最初的申报价值。

编辑:所以为了输出连续的值,则需要更换varlet

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


文章来源: Loops and closures. For and Var