为什么(;;){…}是一个无限循环

Why is for(;;){…} an infinite loop?

本文关键字:一个 无限循环 为什么      更新时间:2023-09-26

可能重复:
循环为空-用于(;;)

我刚刚在UglifyJS(L1045)的JS解析器中发现了一个奇怪的构造:for(;;){…}

我假设一个空条件将解析为undefined,它被转换为布尔值false。但事实并非如此。

显然,它触发了一个无限循环。我能够重现这种行为,但我不知道为什么。有什么(合乎逻辑的)解释吗?

此外:在可能的情况下,为什么while(){…}不起作用?

这只是语义的定义。缺少的"test"表达式被视为值为true的表达式。语言是由人组成的,他们可以自由地指定自己喜欢的任何行为。显然,这种行为是Eich先生喜欢的:-)

for(;;){…}将空条件解释为true,而while(){}不被视为有效。如前所述,它完全依赖于语言,但在规范中进行了描述。

在JavaScript的ECMA-262语言规范(第12.6.3节)中,定义了for循环的行为。

从定义中可以看出,如果分号周围和分号之间的信息不可用,则不存在退出循环的条件。离开循环的唯一方法是定义一个测试条件以及一些可选的开始值和步骤值。

行为可以用不同的方式定义,但事实并非如此。

来自规范

12.6.3 The for Statement
    The production
        IterationStatement : for (ExpressionNoIn(opt) ; Expression(opt) ; Expression(opt)) Statement
    is evaluated as follows:
    1. If ExpressionNoIn is present, then.
        a. Let exprRef be the result of evaluating ExpressionNoIn.
        b. Call GetValue(exprRef). (This value is not used but the call may have side-effects.)
    2. Let V = empty.
    3. Repeat
        a. If the first Expression is present, then
            i. Let testExprRef be the result of evaluating the first Expression.
            ii. If ToBoolean(GetValue(testExprRef)) is false, return (normal, V, empty) .
        b. Let stmt be the result of evaluating Statement.© Ecma International 2011 91
        c. If stmt.value is not empty, let V = stmt.value
        d. If stmt.type is break and stmt.target is in the current label set, return (normal, V, empty) .
        e. If stmt.type is not continue || stmt.target is not in the current label set, then
            i. If stmt is an abrupt completion, return stmt.
        f. If the second Expression is present, then
            i. Let incExprRef be the result of evaluating the second Expression.
            ii. Call GetValue(incExprRef). (This value is not used.

此规范的Gist:当第一个Expression返回"false"值时,for语句停止。

由于缺少表达式不会返回false,因此脚本将永远运行(或者直到从循环体内部执行break语句为止)。