javascript readability continue

¿Por qué las afirmaciones "continuar" son malas en JavaScript?



readability continue (6)

En el libro Javascript: The Good Parts de Douglas Crockford, esto es todo lo que el autor tiene que decir sobre la declaración de continuación:

La instrucción continue salta a la parte superior del ciclo. Nunca he visto un código que no se haya mejorado al refaccionarlo para eliminar la declaración de continue .

Esto realmente me confunde. Sé que Crockford tiene algunas opiniones muy dogmáticas sobre JavaScript, pero esto me suena del todo mal.

En primer lugar, continue hace más que solo saltar al principio de un ciclo. Por defecto, también avanza a la siguiente iteración. Entonces, ¿no es la afirmación de Crockford una información completamente falsa?

Más importante aún, no entiendo completamente por qué continue sería considerado malo. Esta publicación proporciona lo que parece ser la suposición general: ¿por qué continuar dentro de un ciclo es una mala idea?

Aunque entiendo cómo la continue puede hacer que el código sea difícil de leer en ciertas instancias, creo que es tan probable que pueda hacer que el código sea más legible. Por ejemplo:

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

Esto podría refactorizarse en:

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 no es particularmente beneficioso en este ejemplo específico, pero sí demuestra el hecho de que reduce la profundidad de anidación. En un código más complejo, esto podría aumentar la legibilidad.

Crockford no proporciona ninguna explicación de por qué no se debe continue , así que ¿hay algún significado más profundo detrás de esta opinión que me estoy perdiendo?


Continue es una herramienta extremadamente útil para guardar ciclos de cálculo en algoritmos. Claro, se puede utilizar de manera incorrecta, pero también puede hacerlo cualquier otra palabra clave o enfoque. Al esforzarse por el rendimiento, puede ser útil adoptar un enfoque inverso a la divergencia de ruta con un enunciado condicional. Una continuación puede facilitar lo inverso al permitir que las rutas menos eficientes se omitan cuando sea posible.


Douglas Crockford puede sentirse de esta manera porque no cree en la asignación dentro de un condicional. De hecho, su programa JSlint ni siquiera te deja hacerlo, aunque Javascript sí lo hace. Él nunca escribiría:

Ejemplo 1

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

pero, supongo que escribiría algo como:

Ejemplo 2

rec = getrec(); while (rec) { if (!condition(rec)) doSomething(rec); rec = getrec(); }

Ambos funcionan, pero si accidentalmente mezclas estos estilos obtienes un ciclo infinito:

Ejemplo 3

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

Esto podría ser parte de por qué no le gusta continúa.


En realidad, de todo el análisis parece:

  1. Si tiene bucles poco profundos, siéntase libre de usar continue iff; mejora la legibilidad (también puede haber algunas mejoras en el rendimiento).
  2. Si tiene bucles anidados profundos (lo que significa que ya tiene una bola de pelo para desenredar cuando vuelve a factorizar), evitar continuar puede resultar beneficioso desde el punto de vista de la confiabilidad del código.

En defensa de Douglas Crokford, creo que sus recomendaciones tienden a inclinarse hacia la programación defensiva , que, con toda honestidad, parece ser un buen enfoque para ''probar a prueba de idiotas'' el código en la empresa.


La declaración es ridícula. continue puede ser abusado, pero a menudo ayuda a la legibilidad.

Uso típico:

for (somecondition) { if (!firsttest) continue; some_provisional_work_that_is_almost_always_needed(); if (!further_tests()) continue; do_expensive_operation(); }

El objetivo es evitar el código de ''lasaña'', donde tienes condicionales profundamente anidados.

Editado para agregar:

Sí, esto es en última instancia subjetivo. Aquí está mi métrica para decidir.

Editado una última vez:

Este ejemplo es demasiado simple, por supuesto, y siempre puede reemplazar los condicionales anidados con llamadas a funciones. Pero puede que tenga que pasar datos a las funciones anidadas por referencia, lo que puede crear problemas de refactorización al menos tan malos como los que intenta evitar.


Personalmente estoy del otro lado que la mayoría aquí. El problema generalmente no es con los patrones continue muestran, sino con los anidados más profundos, donde las posibles rutas de códigos pueden ser difíciles de ver.

Pero incluso su ejemplo con uno continue no muestra una mejora en mi opinión que sea justificable. Desde mi experiencia, algunas declaraciones continue son una pesadilla para refactorizar más tarde (incluso para los lenguajes estáticos más adecuados para la refactorización automatizada como Java, especialmente cuando alguien más tarde también break ).

Por lo tanto, agregaría un comentario a la cita que me diste:

La refactorización para eliminar la declaración de continue aumenta su capacidad de refactorización.

Y los bucles internos son realmente buenos para, por ejemplo, extraer la función . Tal refactorización se realiza cuando el ciclo interno se vuelve complejo y luego continue puede hacer que sea doloroso.

Estas son mis opiniones honestas después de trabajar profesionalmente en proyectos de JavaScript en un equipo, allí las reglas que Douglas Crockford habla realmente muestran sus méritos.


Personalmente, nunca escuché nada malo sobre el uso de la declaración de continuación. Es cierto que podría (la mayoría de las veces) evitarse fácilmente, pero no hay razón para no usarlo. Encuentro que los bucles pueden ser mucho más limpios y legibles con declaraciones continuas en el lugar.