qwe*_*xcj 3 javascript closures for-loop ecmascript-6
有人解释一下这个(var 和 let in for 循环之间的行为差异)吗?
经典面试题(结束语):
let a = [];
for (var i=0; i<10; i++) {
a[i] = function() {
console.log(i,);
}
}
a[0](); // 10
a[1](); // 10
Run Code Online (Sandbox Code Playgroud)如果我们使用让:
let a = [];
for (let i=0; i<10; i++) { // var => let
a[i] = function() {
console.log(i);
}
}
a[0](); // 1
a[1](); // 2
Run Code Online (Sandbox Code Playgroud)是的,我在使用“让”时正常并且符合预期。我想到的第一个想法是 let 不支持关闭。但不,它支持。(随后在 Chrome 上对其进行了测试):
function bb() {
let b = 1;
return function() {
console.log(b);
}
}
bb()(); // 1, means a closure is created
Run Code Online (Sandbox Code Playgroud)
那么我的第二个解释是:当在 for 循环中使用 let 时。对于每个循环,它会反复创建一个新的 i。我在 chrome 调试器中证明了这一点。
问题是:
如果在 for 循环的每个循环中都创建了 i。怎么一直增加???如果每次都创建它,为什么它不会像我们声明的那样保持为 0?
for (let i=0; .......)
Run Code Online (Sandbox Code Playgroud)
根据您的示例,let i每次迭代都会创建“词法声明”的环境。但是,for循环使用前一个环境来创建下一个环境。所以当增量发生时,它从它停止的地方开始。否则使用let声明i将创建一个无限循环(即i总是<10)。
这个怎么运作:
在 for 循环体评估中,'test' 和 'result' 之后的步骤是CreatePerIterationEnvironment(perIterationBindings),它声明一个新环境并将所有绑定初始化为其最后一个已知值:thisIterationEnv.InitializeBinding(bn, lastValue)。完成后,新环境将设置为当前环境,然后“增量”步骤开始。
定义:
InitializeBinding(N,V) 设置环境记录中已经存在但未初始化的绑定的值。字符串值 N 是绑定名称的文本。V 是绑定的值,是任何 ECMAScript 语言类型的值。