[英]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
是函数作用域的(也就是说,具有周围函数的作用域),而let
& const
是块作用域的-因此在每个块中都有自己的值( 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.