-4

I don't think any of them are good practice. In addition to that they make the code longer.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for

Optional initialization

var i = 0;
for (; i < 9; i++) {
    console.log(i);
    // more statements
}

Disadvantages:

  • Can have side effects

Optional condition

for (let i = 0;; i++) {
   console.log(i);
   if (i > 3) break;
   // more statements
}

Disadvantages

  • The only use case I can think of is when you are using this construct is when you are programming a microcontroller that waits for an input. Other than that, I simply don't know what you gain by pulling the condition inside the for-loop.

Optional final-check

for (let i = 0;i < 3;) {
   console.log(i);
   i++;
   // more statements
}

Disadvantages

  • This is so useless. I don't know what to think of it

All expression optional

var i = 0;

for (;;) {
  if (i > 3) break;
  console.log(i);
  i++;
}

Disadvantages

  • This combines all the disadvantages from above

I fail to see the benefit of using optional expressions in for-loops. But maybe I'm missing something? Could someone provide examples where the optional for-loop statement is superior to the standard for-loop?

4
  • 1
  • @gnat oh, gee. What do I do if I want to have insights from other people to that question? I'm sure it is of interest to other people as well and it is a software engineering question. Commented May 4, 2020 at 18:46
  • 1
    As a mentor to aspiring programmers, I recommend either a counted for-loop when you know exactly how many times to loop, or else an infinite loop (using either for(;;) { or while(1){. For certain looping patterns (e.g. prompt first then ask for input, retry if necessary) it seems to reduce the cognitive load to allow the exit condition to be stated inside the loop and where/when it naturally occurs rather than trying to shoehorn into a while (or for-loop) using a non-vacuous condition.
    – Erik Eidt
    Commented May 4, 2020 at 19:19
  • those are set for optional so that in some cases, you can use that feature when you don't have to add that one or more parameter.whether its initialization, limit, or increment/decrement.
    – Ishan Shah
    Commented Jul 21, 2020 at 6:23

4 Answers 4

2

It all depends on what you do with i.

There are cases where you need to use it later on, for instance to check whether the for terminated early or not:

let i = 0;
for (; i < a.length; ++i) {
   ...
}

if (i === a.length) {
    ...
}

Another way to write this code would be to introduce a boolean variable, or to completely rewrite the code.

Similarly, the final expression may be slightly more complex than a ++ operator. Here's an example:

for (let i = 0; i < a.length;) {
    ...
    if (something(value)) {
        // Go back one element: we need to replay it on the next iteration.
        --i;
    } else if (someOther()) {
        // Specific case where the whole array needs to be read again.
        i = 0;
    } else {
        // Continue.
        ++i;
    }
}

Note that the code above is quite unusual, and can possibly be rewritten in a way which would make it more readable and make errors more difficult.

Finally, the condition may not be needed if you're in an infinite loop. As simple as that.

for (;;) {
    processEvents();
}
2
  • The second example is what I mean with bad practice. This is hard to reason about. Commented May 4, 2020 at 19:34
  • @thadeuszlay: it is, but it can be quite challenging to write differently. Imagine your code is processing, say, a list of tokens. Usually, you need to go forward, but sometimes you need to go one token back, or to rewind to a specific position. How would you write that? Commented May 4, 2020 at 19:45
2

In the integer-counting loop it's typically nonsense to pull out any part of the for statement. So, when looking only at integer-counting loops, you're right with your conclusion.

But there are other uses cases than that. E.g. in old-style Java (before Java 5), iterating over a list was typically written as

for (Iterator iter = list.iterator(); iter.hasNext(); ) {
    Object element = iter.next();
    // do something with the element
}

As the iter.next() call both delivers the next element and advances one position in the list, that can hardly be put into the third place of the for statement. And there are numerous other use cases where one or the other place is best left empty.

1

In counted for loops (for ( int i = 0; i < n; i++) { ... }) the continue; statement includes the increment (i++), whereas meaning of continue; in the version where you place the increment inside the loop is different.

1

When i is just a simple loop counter, the full syntax capability of a for-loop is probably going to look overcomplicated and overengineered. But not all iterators are just simple loop counter, sometimes they're a bit more complicated.

Optional initialisation is useful if you want to statefully resume iteration at the point where a previous loop stopped with different loop body:

let i = currentPos;
for (; isSad(arr[i]); i++) {
    cheerUp(i);
}
for (; isHappy(arr[i]); i += 2) {
    extractHoney(i);
}

The optional increment expression is useful when you need to work with iterators which doesn't necessarily have a simple ++ or -- semantic:

for (let robot = Robot(); robot.reachesGoal(); ) {
    if (robot.seesObstacle()) {
        robot.jumpForward();
    } else if (robot.seesFlag()) {
        robot.grabFlag();
        robot.turnLeft();
        robot.walkForward(5);
        robot.turnRight();
    }
        robot.walkForward(1);
    }
}

Finally, optional loop condition are useful whenever you used a break or continue statement, or whenever you needed an infinite loop.

Not the answer you're looking for? Browse other questions tagged or ask your own question.