代码之家  ›  专栏  ›  技术社区  ›  Adelin

为什么让不慢于var?

  •  9
  • Adelin  · 技术社区  · 7 年前

    做一个极端的总结, the difference between var and let 他们的生活在一个范围内。

    所以如果我们要从 this answer

    (function() {
      for (var i = 0; i < 5; i++) {
        setTimeout(function() {
          console.log(`i: ${i}`);
        }, i * 100);
      }
      // 5, 5, 5, 5, 5
    
    
      for (let j = 0; j < 5; j++) {
        setTimeout(function() {
          console.log(`j: ${j}`);
        }, 1000 + j * 100);
      }
      // 0, 1, 2, 3, 4
    }());
    • i (声明 风险价值 function
    • j (声明 )只生活在 for 循环。

    对我来说,这意味着javascript在每次迭代之后,除了声明和分配变量之外,在 它还需要执行一个额外的步骤:清理 j型

    the specs 对,还有很多:

    1. 在这种情况下 风险价值 ,执行以下步骤:

    迭代语句:for(Expressionopt;Expressionopt;Expressionopt)语句

      • 让exprRef作为计算第一个表达式的结果。
      • 设exprValue为GetValue(exprRef)。
    1. 返回ForBodyEvaluation(第二个表达式、第三个表达式、语句、labelSet)。
    1. 但在这种情况下

      迭代语句:(LoalCalpalExpPosiPopt;ExpStudiopt)语句

      1. 让OLDNV成为运行环境下的词汇环境。
      2. 让loopEnv成为NewDeclarativeEnvironment(oldEnv)。
      3. 设isConst是执行IsConstantDeclaration of>1的结果。词汇声明。
      4. 让地名成为词汇宣言的界名。
      5. 对于boundNames的每个元素dn
          • 执行loopEnv.CreateImmutableBinding(dn,true)。
        • 否则,
          • 断言:上面对CreateMutableBinding的调用永远不会返回突然完成的结果。
      6. 将运行执行上下文的词汇环境设置为LoOpenV。
      7. 让FordCL是评价词汇声明的结果。
      8. 如果forDcl是一个突然的完成,那么
        • 将运行的执行上下文词汇环境设置为OLDNV。
        • 返回完成(forDcl)。
      9. 如果isConst为false,则让pererationlets成为boundNames,否则让pererationlets成为boundNames。
      10. 设bodyResult为bodyEvaluation(第一个表达式、第二个表达式、语句、包运算、标签集)。
      11. 将运行的执行上下文词汇环境设置为OLDNV。

    为什么在运行下面的测试时 the same question I previously referenced 风险价值 ,反之亦然,正如我所料?

    (function() {
      let varTime = performance.now()
      for (var i = 0; i < 100000000; i++) {}
      varTime = performance.now() - varTime;
      console.log('var', varTime)
    
    
      let letTime = performance.now()
      for (let i = 0; i < 100000000; i++) {}
      letTime = performance.now() - letTime;
      console.log('let', letTime)
    }).call({});
    TEST 1
    var: 147.500ms
    let: 138.200ms
    
    TEST 2
    var: 141.600ms
    let: 127.100ms
    
    TEST 3
    var: 147.600ms
    let: 122.200ms
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Jee Mok ecanf    7 年前

    我同意@Derek的观点,如果不深入到实现中去,很难找到理由。

    但是,你可能错过了一些步骤 var :

    风险价值 ,实际上 更多

    迭代语句:for(Expressionopt;Expressionopt;Expressionopt)语句

    1. 如果第一个表达式存在,则
      • 让exprRef作为计算第一个表达式的结果。
      • 让exprValue成为 (扩展)。
        • 如果类型(V)不是引用,则返回V。
        • 设base为GetBase(V)。
        • 如果是属性引用(V),则
          • 如果HasPrimitiveBase(V)为true,则
            • 设base为object(base)。
          • 返回基。[[Get]](GetReferencedName(V),GetThisValue(V))。
          • 返回base.GetBindingValue(GetReferencedName(V),IsStrictReference(V))(见8.1.1)。
      • 返回值(exprValue)。
    2. 返回ForBodyEvaluation(第二个表达式、第三个表达式、语句、labelSet)。

    这个 轻微地 其他处理可以来自 GetValue