【问题标题】:hidden increment of variable occurres变量的隐藏增量发生
【发布时间】:2013-12-26 12:52:52
【问题描述】:

这里的基本问题.. 第二个console.log(k); 打印出 10 而不是 9,这是为什么呢?

function test (o) {
  var i = 0;
  if(typeof o == "object") {
      var j = 0;
      for(var k=0;k<10;k++){
          console.log(k);
      }
      console.log(k);
  }
  console.log(j);
}

test(o);

【问题讨论】:

  • 10 被打印是因为 JavaScript 没有块作用域,并且当 k &lt; 10 失败时,k10
  • @Juhana 对不起,我没有仔细阅读
  • @Blender: k 没有设置为其他值或被遮蔽,我看不出 JavaScript 缺少块范围有何改变。
  • k 在打印 log(k) 之前获取增量,所以使用 while 循环它会为你工作
  • @Qantas94Heavy:您在循环之外引用它。类似的代码在具有块作用域的 C++ 中不起作用。

标签: javascript variables loops scope


【解决方案1】:

简短的回答是:如果您期望 k 为 9,那么您不能期望 for 循环同时结束,因为 if (k === 9) console.log(k&lt;10); 将记录 true,因此您的第二个 console.log(k) 不会被执行。
就是这样。现在长答案:

嗯,基本上,for 循环由 3 个不同的语句组成:

for (var k=0;k<10;k++)

你需要了解 JS 何时会执行每条语句。在第一种情况下,它非常简单:

k=0

当JS进入循环时赋值被执行,然后(在执行循环之前)条件将被评估:

k<10 // == 0 < 10 == true

循环体被执行,然后评估条件之前,执行第三条语句:

k++//increment k, k is 1 now

一切都好,现在假设

for(k=9;k<10;k++)

并应用相同的逻辑。循环体将执行一次,k 递增,现在保持 10 作为值。条件评估为假,JS 将不再循环。
因为 JS 不是真正的块作用域,k 会很高兴地驻留在内存中,直到再次需要它为止,并且由于您没有重新分配它,它仍将 10 作为值。

真的是那么简单。它实际上就像我所知道的大多数语言一样......

【讨论】:

  • 谢谢埃利亚斯!高质量的答案,你解释了整点。这实际上是书中涵盖函数范围的示例,但他们没有解释第二个变量 k 结果。
【解决方案2】:

在这一行

for(var k=0;k<10;k++){
  console.log(k);
}

k 增加了 k++ 增量器。在最后一次迭代中,k = 10 然后条件失败,下一个console.log(k)k 的值打印为10

【讨论】:

    【解决方案3】:

    直到“k

    当然,循环内部只有在条件成功时才会运行,这就是为什么它会在“9”处停止。

    旁注

    顺便说一句,这整个语句首先起作用的原因是因为 javascript 不像其他语言那样强制执行变量范围。换句话说,在许多语言中,如果您在循环中声明一个变量,则不允许在循环之外使用该变量(至少如果该变量是原始类型)。

    我意识到这个问题可能完全是学术问题,但总的来说,我的策略是在 javascript 中使用“var”关键字声明变量,以确保我不会覆盖全局变量,并且我也尽量避免出现这种情况通过遵守“C”遗产范围规则。换句话说,尽管这是一个有趣的问题 - 它是一种可能应该避免的编码实践。希望以后能给其他人一些指导!

    【讨论】:

    • 迂腐注:for(k=9;k&lt;10;k++) k +=101;。在这种情况下,k 不会 等于 10,但循环仍将退出。从这个意义上说,您的答案不正确或不完整
    • @EliasVanOotegem 你是对的。将相应地更新措辞。
    • 你的旁注是个好建议,这个例子来自于解释函数范围的学术目的的书中,应该避免。
    【解决方案4】:
    • “for”循环只要 k
    • 在循环结束时 } 它必须根据 k++ 递增 k,这意味着 k=k+1 使得 k=10
    • 根据您的 k

    【讨论】:

      猜你喜欢
      • 2012-11-05
      • 2020-05-14
      • 1970-01-01
      • 2019-06-07
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多