让vs var:scopes在for-loop [英] let vs var: scopes in for-loop

查看:211
本文介绍了让vs var:scopes在for-loop的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人解释这一点(var和let在for循环中的行为差异)。

Anyone explain this(behavior differences between var and let in for loop) please?


  1. classical interview question(closure):

let a = [];
for (var i=0; i<10; i++) {
    a[i] = function() {
      console.log(i,);
    }
}
a[0](); // 10
a[1](); // 10


  • 如果我们使用let:

  • if we use let:

    let a = [];
    for (let i=0; i<10; i++) {    // var => let
        a[i] = function() {
        console.log(i);
      }
    }
    
    a[0](); // 1
    a[1](); // 2
    


  • 如使用'let'时所期望的。
    第一个想法来到我的想法是让let不支持闭包。但不,它支持。 (以下在Chrome上测试):

    Yes, i is normal and as expected when using 'let'. The first thought came to my mind is that let doesnt support closure. But no, it supports. (following tested it on Chrome):

    function bb() {
      let b = 1;
      return function() {
        console.log(b);
      }
    }
    bb()();    // 1, means a closure is created
    

    然后我的第二个解释是:当使用let in for loop 。对于EVERY循环,它重复创建一个新的。这是我在chrome调试器中证明。

    Then my second explanation is: when using let in for loop. For EVERY loop, it creates a new i repeatedly. And this is proved in chrome debugger by me.

    问题是:

    在for循环中。如何保持增长???为什么它不只是保持为0,因为我们声明它是否每次都创建?

    if i is created in each loop in the for-loop. How does it keeps increasing??? Why it doesn't just keep being 0 as we declared if it is created every time?

    for (let i=0; .......)
    


    推荐答案

    ,在每次迭代中创建词法声明的环境 let i 。但是, for 循环使用以前的环境,以创建下一个环境。所以当增量出现时,它从它停止的地方开始。否则使用 let 来声明 i 会创建一个无限循环(即 i 总是< 10 )。

    From your example, the environment for the "lexical declaration" let i is being created every iteration. However, the for loop uses the previous environment in order to create the next environment. So when the increment occurs it begins where it left off. Otherwise using let to declare i would create an infinite loop (i.e. i would always be <10).

    工作原理:

    在for循环中身体评估< a>,测试和结果之后的步骤是 CreatePerIterationEnvironment( perIterationBindings),它声明一个新的环境并将所有绑定初始化为它们最后的已知值: thisIterationEnv.InitializeBinding(bn,lastValue)。一旦完成,新环境将设置为当前环境,并开始增量步骤。

    In the for loop body evaluation, the step after 'test' and 'result' is CreatePerIterationEnvironment(perIterationBindings) which declares a new environment and initializes all the bindings to their last known value: thisIterationEnv.InitializeBinding(bn, lastValue). Once complete the new environment is set as the current environment and the 'increment' step begins.

    定义:

    InitializeBinding(N,V)设置环境记录中已存在但未初始化的绑定的值。字符串值N是绑定名称的文本。 V是绑定的值,是任何ECMAScript语言类型的值。

    InitializeBinding(N,V) Set the value of an already existing but uninitialized binding in an Environment Record. The String value N is the text of the bound name. V is the value for the binding and is a value of any ECMAScript language type.

    这篇关于让vs var:scopes在for-loop的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆