Почему операторы "continue" плохи в JavaScript?

в книге Javascript: Хорошие Части Дуглас Крокфорд, это все, что автор может сказать о заявлении continue:

на continue оператор переходит в верхнюю часть цикла. Я никогда не видел фрагмент кода, который не был улучшен путем его рефакторинга, чтобы удалить continue заявление.

это действительно смущает меня. Я знаю, что у Крокфорда есть некоторые очень самоуверенные взгляды на JavaScript, но это просто звучит полностью неправильно для меня.

прежде всего,continue делает больше, чем просто прыгать в верхней части цикла. По умолчанию, он также переходит к следующей итерации. Так не является ли заявление Крокфорда полностью ложной информацией?

что еще более важно, я не совсем понимаю, почему continue даже будет считаться плохим. Эта должность обеспечивает то, что кажется общим предположением: почему продолжать внутри цикла плохая идея?

хотя я понимаю, как continue может затруднить чтение кода в некоторых случаях, я думаю, что это так же вероятно, что он может сделать код более читаемым. Например:

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);
        }
    }
}

это может быть разделено на:

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 не особенно полезно в этом конкретном примере, но он демонстрирует тот факт, что он уменьшает глубину вложенности. В более сложном коде это потенциально может повысить читаемость.

Крокфорд не дает никаких объяснений, почему continue не следует использовать, так есть ли какое-то более глубокое значение за этим мнением, которое мне не хватает?

6 ответов


утверждение нелепо. continue можно злоупотреблять, но это часто помогает читабельности.

типичное использование:

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

    some_provisional_work_that_is_almost_always_needed();

    if (!further_tests()) continue;

    do_expensive_operation();
}

цель состоит в том, чтобы избежать кода "лазанья", где у вас есть глубоко вложенные условные обозначения.

редактировать, чтобы добавить:

Да, это в конечном счете субъективная. вот моя метрика для принятия решения.

отредактировано в последний раз:

этот пример слишком простой, конечно, и вы всегда можете заменить вложенные условные обозначения вызовами функций. Но тогда вам, возможно, придется передавать данные во вложенные функции по ссылке, что может создать проблемы рефакторинга, по крайней мере, такие же плохие, как те, которых вы пытаетесь избежать.


Я лично на другой стороне, чем большинство здесь. Проблема обычно не в показанном continue шаблоны, но с более глубоко вложенными, где возможные пути кода могут стать трудными для просмотра.

но даже ваш пример с одним continue не показывает улучшения, на мой взгляд, это оправданно. Из моего опыта несколько continue заявления кошмар рефакторинг позже (даже для статических языков, лучше подходящих для автоматического рефакторинга, таких как Java, особенно когда кто-то позже ставит там break тоже).

таким образом, я бы добавил комментарий к цитате, которую вы дали:

рефакторинг, чтобы удалить continue оператор inreases ваша дальнейшая способность рефакторинга.

и внутренний циклы-это действительно хороший candidated, например,извлечь функция. Такой рефакторинг выполняется, когда внутренний цикл становится сложным, а затем continue может сделать больно.

это мои честные мнения после профессиональной работы над проектами JavaScript в команде, есть правила, о которых говорит Дуглас Крокфорд, действительно показывают свои достоинства.


Дуглас Крокфорд может чувствовать себя так, потому что он не верит в назначение в рамках условного. На самом деле, его программа JSlint даже не позволяет вам это сделать, хотя Javascript делает. Он никогда не напишет:--4-->

Пример 1

while (rec = getrec())
{   
    if (condition1(rec))
        continue;

    doSomething(rec);
}

но, я думаю, он б напишите что-нибудь вроде:

Пример 2

rec = getrec();

while (rec)
{   
    if (!condition(rec))
        doSomething(rec);

    rec = getrec();
}

оба эти работают, но если вы случайно смешиваете эти стили, вы получаете бесконечная петля:

Пример 3

rec = getrec();

while (rec)
{   
    if (condition1(rec))
        continue;

    rec = getrec();
}

Это может быть частью того, почему он не любит по-прежнему.


Continue-чрезвычайно полезный инструмент для сохранения вычислительных циклов в алгоритмах. Конечно, его можно неправильно использовать, но так же может любое другое ключевое слово или подход. При стремлении к производительности может быть полезно использовать обратный подход к дивергенции пути с условным утверждением. Продолжение может облегчить обратное, позволяя пропускать менее эффективные пути, когда это возможно.


на самом деле, из всего анализа кажется:

  1. Если у вас есть неглубокие петли-не стесняйтесь использовать continue iff это улучшает читаемость (также, там мая некоторые повышения производительности?).
  2. Если у вас есть глубокие вложенные петли (что означает, что у вас уже есть комок волос, чтобы распутать, когда вы повторно фактор), избегая продолжить может оказаться полезным с точки зрения надежности кода.

в защиту Дугласа Крокфорда, я чувствую, что его рекомендации склонны склоняться к защитное Программирование, что, честно говоря, кажется хорошим подходом для "идиотской проверки" кода на предприятии.


лично я никогда не слышал ничего плохого о используя оператор continue. Это правда ,что этого можно (большую часть времени) легко избежать, но нет причин не использовать его. Я считаю, что циклы могут быть намного чище и более читаемыми с помощью инструкций continue.