Why are "continue" statements bad in JavaScript?

twiz picture twiz · Jul 30, 2012 · Viewed 18.5k times · Source

In the book Javascript: The Good Parts by Douglas Crockford, this is all the author has to say about the continue Statement:

The continue statement jumps to the top of the loop. I have never seen a piece of code that was not improved by refactoring it to remove the continue statement.

This really confuses me. I know Crockford has some very opinionated views on JavaScript, but this just sounds entirely wrong to me.

First of all, continue does more than just jump to the top of a loop. By default, it also progresses to the next iteration. So isn't Crockford's statement just completely false information?

More importantly, I do not entirely understand why continue would even be considered to be bad. This post provides what seems to be the general assumption: Why is continue inside a loop a bad idea?

Although I understand how continue may make code difficult to read in certain instances, I think it is just as likely that it can make code more readable. For instance:

var someArray=['blah',5,'stuff',7];
for(var i=0;i<someArray.length;i++){
    if(typeof someArray[i]==='number'){
        for(var j=0;j<someArray[i];j++){
            console.log(j);
        }
    }
}

This could be refactored into:

var someArray=['blah',5,'stuff',7];
for(var i=0;i<someArray.length;i++){
    if(typeof someArray[i]!=='number'){
        continue;
    }
    for(var j=0;j<someArray[i];j++){
        console.log(j);
    }
}

continue isn't particularly beneficial in this specific example, but it does demonstrate the fact that it reduces the nesting depth. In more complex code, this could potentially increase readability.

Crockford provides no explanation as to why continue should not be used, so is there some deeper significance behind this opinion that I am missing?

Answer

egrunin picture egrunin · Jul 30, 2012

The statement is ridiculous. continue can be abused, but it often helps readability.

Typical use:

for (somecondition)
{
    if (!firsttest) continue;

    some_provisional_work_that_is_almost_always_needed();

    if (!further_tests()) continue;

    do_expensive_operation();
}

The goal is to avoid 'lasagna' code, where you have deeply nested conditionals.

Edited to add:

Yes, this is ultimately subjective. Here's my metric for deciding.

Edited one last time:

This example is too simple, of course, and you can always replace nested conditionals with function calls. But then you may have to pass data into the nested functions by reference, which can create refactoring problems at least as bad as the ones you're trying to avoid.