8

While reading code from a JS Editor (Tern), I have come across various uses for the for-loop as seen in the snippets below:

code snippet 1 @ lines 463-468:

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

code snippet 2 @ lines 97-100

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

On the same note, I also have come across a for-loop with an empty body e.g:

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

I am trying to understand what happens in code execution flow.

My take is that for code in snippet 1, the for loop has no conditions, so it may continue endlessly? For code in snippet 2, i is continually incremented without a limit? For the third one, the loop continues till p is assigned something that evaluates to false?

These are the ideas I have in my mind yet I am not sure. Please assist.

1
  • 4
    You are correct. The first two loops can finish if there is a break in their bodies. Commented Aug 5, 2013 at 13:30

2 Answers 2

5

In Short

First of all you are correct in all your assertions.

  • The first loop runs until it is exited from abruptly (with a break, return, throw etc..).
  • The second loop runs until it is exited from abruptly but also performs a variable assignment, and increments a value.
  • The third for loop runs like a normal for loop until the center condition is falsey. Its body is empty.

But Why does JavaScript do this?

Let's dig into why this happens.

If we take a closer look at the language specification we can see that the following happens in a for loop:

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

I will treat these statements and that definition for the rest of the answer.

Now let's go through the cases.

In case one of for(;;) the following happens:

  • ExpressionNoIn is not present, so nothing is called for that clause (As clause 1 states).

  • The second expression is not in, so we do not return calls (as clause 3 states).

  • The third expression is empty so no "incremenetion" is performed (as clause 3.f states).

So it would basically repeat endlessly just as you predicted (until broken from with a break or returned from, or thrown from and generally anything that causes abrupt completion). (As clauses e and d tell us).

In the second case for (var i = 0; ; ++i) the following happens:

  • ExpressionNoIn is present, so we evaluate it, and assign it with get value (as clause 1 states). We do not assign it.

  • Then we repeat endlessly since the second expression is not here. So we continue until abrubt execution happens or a break happens. More specifically this is defined here.

  • We increment i on every iteration as clause f states.

In the third case for (var p; p; p = someValue) /* empty body */ ; the following happens:

This evaluates as a for loop. Statement is empty indeed but the for loop does not really care. The only difference is that no value is returned from the for loop. Basically it's a full and legal for loop. ; is simply an empty statement. It is useful when you want to run a for loop with no content in the actual loop. You see this sometimes in feature detection. This is also useful when you want to find the minimum n such that... .

You are correct in that it runs until the value is falsey, or more accurately calling ToBoolean on it produces false. As clause 3.a.ii specifies.

As you can see, this is all in the spec and well defined :)


Why do coders do this?

In the first snippet the perform their flow control with a break clause. if (eol >= pos || eol < 0) break; (they check for the end of line, and this could be done in a more conventional for loop).

In the second snippet again they do flow control using break:

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

They again put it in a break statement inside the for loop.

The third snippet is out of context, but let's say we want to (trivial example) find the first number bigger than 10 (or the 10th div element, or occurance of a string - you get the idea). We could do :

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

And get the first number bigger than 10.

Sign up to request clarification or add additional context in comments.

2 Comments

Why wouldn't you use while (true)?
@Nate For example when code golfing for(;;) is shorter :P Honestly there is no good reason to use for(;;) I explained why it behaves this way and not why one would use it in code.
1

You are correct in your understanding.

The first snippet is an infinite loop; there is no termination condition, so the loop will (in itself) continue forever. This is almost certainly accompanied by a break statement somewhere within the body, which will exit the loop when it is run. (The other option is that a thrown exception exits the loop, although it is bad practice to use exceptions as control flow.) This pattern (or an equivalent while (true) {...} ) usually occurs when the exit condition is too complex to express within the loop statement.

The second snippet is similar to the first, in that without a termination condition it will run forever. This will also require a break statement (or exception) to terminate the loop. The only difference here is that a counter variable is also being incremented on each iteration.

The third snippet is a loop with no body, though the test and variable update happen on each iteration of the loop. As you expected, this continues until p evaluates to false. This for loop is exactly equivalent to the while loop version:

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

which perhaps makes it clearer that the assignment happens repeatedly until !p.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.