繁体   English   中英

更好地理解JavaScript for循环

[英]Understanding JavaScript for-loop better

在从JS编辑器( Tern )中读取代码时,我遇到了for循环的各种用法,如下面的代码片段所示:

代码段1 @ lines 463-468

for (;;) {
  /* some code */
}

代码片段2 @ 行97-100

for (var i = 0; ; ++i) {
  /* some code */
}

同样,我也遇到了一个带有空体的for循环,例如:

for (var p; p; p = someValue) /* empty body */ ;

我试图了解代码执行流程中发生了什么。

我的看法是,对于代码片段1,for循环没有条件,所以它可能会无休止地继续下去? 对于代码段2中的代码, i不断增加而没有限制? 对于第三个,循环继续,直到p被赋予评估为false东西?

这些是我脑子里的想法,但我不确定。 请协助。

简而言之

首先,你的所有断言都是正确的。

  • 第一个循环一直运行,直到它突然退出(中断,返回,抛出等)。
  • 第二个循环一直运行,直到它突然退出,但也执行变量赋值,并递增一个值。
  • 第三个for循环运行就像一个正常的循环,直到中心条件为假。 它的身体是空的。

但为什么JavaScript会这样做?

让我们深入研究为什么会发生这种情况。

如果我们仔细研究语言规范,我们可以看到在for循环中发生以下情况:

IterationStatement:for(ExpressionNoIn(opt); Expression(opt); Expression(opt))Statement

对于其余的答案,我将对这些陈述和该定义进行处理。

现在让我们来看看案例。

如果for(;;)之一发生以下情况:

  • ExpressionNoIn不存在,因此没有为该子句调用任何内容(As子句1指出)。

  • 第二个表达式不在,所以我们不返回调用(如第3条所述)。

  • 第三个表达式为空,因此不执行“增量”(如3.f状态)。

所以它基本上会像你预测的那样无休止地重复(直到从break或者从break或从中抛出,并且通常是任何导致突然完成的事物)。 (正如条款e和d告诉我们的那样)。

在第二种情况下for (var i = 0; ; ++i)发生以下情况:

  • ExpressionNoIn存在,所以我们对它进行评估,并为其赋值get(如第1条所述)。 我们不指定它。

  • 然后我们无休止地重复,因为第二个表达不在这里。 所以我们继续,直到abrubt执行发生或发生中断。 更具体地说,这是此定义的。

  • 我们在每次迭代时递增i ,如f条款所述。

在第三种情况下for (var p; p; p = someValue) /* empty body */ ; 发生以下情况:

这被评估为for循环。 语句确实是空的,但for循环并不真正关心。 唯一的区别是for循环没有返回任何值。 基本上它是一个完整且合法的循环。 ; 只是一个空洞的陈述。 当您想要在实际循环中运行没有内容的for循环时,它非常有用。 你有时会在特征检测中看到这一点。 当您想要找到最小n时,这也很有用....

你是正确的,它运行直到值为false,或更准确地调用它上面的ToBoolean产生 false 如第3.a.ii条规定。

正如你所看到的,这都是在规范和定义良好:)


编码器为什么要这样做?

在第一个片段中, 使用break子句执行其流控制。 if (eol >= pos || eol < 0) break; (他们检查线路的末端,这可以在更传统的for循环中完成)。

在第二个片段中,他们使用break进行流量控制:

 if (!definitions.hasOwnProperty(uniq)) { name = uniq; break; }

他们再次将它放在for循环中的break语句中。

第三个片段是脱离上下文的,但是假设我们想要(通常的例子)找到大于10的第一个数字(或第10个div元素,或者出现一个字符串 - 你明白了)。 我们可以这样做:

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

得到第一个大于10的数字。

你的理解是正确的。

第一个片段是无限循环; 没有终止条件,所以循环(本身)将永远继续。 这几乎肯定伴随着身体内某处的break语句,它将在运行时退出循环。 (另一种选择是抛出异常退出循环,尽管使用异常作为控制流是不好的做法。)这种模式(或等效的while (true) {...} )通常在退出条件过时发生复杂在循环语句中表达。

第二个片段类似于第一个片段,因为没有终止条件它将永远运行。 这还需要break语句(或异常)来终止循环。 这里唯一的区别是计数器变量也在每次迭代时递增。

第三个片段是一个没有主体的循环,尽管测试和变量更新发生在循环的每次迭代中。 如您所料,这将一直持续到p评估为false 这个for循环完全等同于while循环版本:

var p;
while (p) {
    p = someValue;
}

也许更清楚的是,任务重复发生,直到!p

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM