为什么for(;;){...}是一个无限循环?

3
可能重复:
空的for循环 - for(;;) 我在UglifyJS的JS解析器中(位于L1045)发现了一种奇怪的结构:for(;;){…}
我认为一个空条件会转换为undefined,这会转换为布尔值false。但事实并非如此。
显然,它会触发无限循环。我能够复制这种行为,但我不知道为什么。有任何(逻辑上的)解释吗?
另外:既然这是可能的,为什么不能使用while(){…}
4个回答

4

这只是语义的定义。如果缺少“test”表达式,则会将其视为具有值true的表达式。语言是由人创造的,他们可以自由地指定任何他们喜欢的行为。显然,这种行为是Eich先生所喜欢的 :-)


3
这是它的规格说明:http://es5.github.com/x12.html#x12.6.3 - Mathias Bynens
哦,谢谢。不知道为什么,它一直加载很久了,对我来说。 - Pointy
显然这不是 Eich 先生喜欢的唯一奇怪的事情;) - Christoph
是的,但总体来说我很欣赏他的工作! - Pointy
实际上,那种行为是Dennis Ritchie喜欢的,因为它是从C语言继承来的 ;) 尽管如此,也许C语言是从早期的B或BCPL语言中得到的。 - Matthew Crumley
嘿,这是一个很好的观点。我已经很久没有写C程序了,所以我甚至没有想到过这个问题。不过你说得对,现在想起来确实如此。我想我从来没有觉得这是奇怪的行为;我猜这只是一个期望的问题。 - Pointy

4

for(;;){…}会将空条件解释为true,而while(){}则不被视为有效。正如前面所说,这完全取决于语言,但在规范中有描述。


1

来自规范

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 StatementEcma 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.

本规范的要点: 当第一个表达式返回“falsey”值时,for语句停止。

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


1
JavaScript的ECMA-262语言规范(第12.6.3节)中定义了for循环的行为方式。
从定义中可以看出,如果分号周围和之间的信息不可用,则没有条件离开循环。唯一离开循环的方法是定义一个测试条件,以及可选的起始和步进值。
行为方式可以以不同的方式定义,但事实就是这样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接