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.
breakin their bodies.