为什么JavaScript中的“continue”语句不好?

在书中Javascript:好部分由道格拉斯克罗克福德,这是所有作者不得不说继续声明:

continue语句跳转到循环的顶部。 我从来没有看到过一个代码没有通过重构来消除continue语句的改进。

这真让我困惑。 我知道Crockford对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并不是特别有益,但它确实certificate了它降低了嵌套深度。 在更复杂的代码中,这可能会增加可读性。

克罗克福德没有解释为什么不应该continue使用,那么在这个意见背后有什么更深的意义,我失踪了?

这个陈述是荒谬的。 continue可以被滥用,但它往往有助于可读性。

典型用途:

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

目标是避免“宽面条”的代码,你有深嵌套的条件。

编辑添加:

是的,这是最终的主观。 这是我决定的指标。

最后一次编辑:

当然,这个例子太简单了,你可以用函数调用来replace嵌套的条件。 但是你可能不得不通过引用将数据传递给嵌套的函数,这可能会导致重构问题,至less和你想要避免的一样糟糕。

我个人比这里的大多数都要多。 问题通常不是显示的continue模式,而是更深的嵌套模式,在可能的代码path可能很难看到。

但是,即使你的榜样continue ,我认为没有任何改善是合理的。 从我的经验来看,一些continue声明对于后来的重构来说是一场噩梦 (甚至对于更适合像Java这样的自动化重构的静态语言,尤其是当某个人稍后也放弃了这种重构时)。

因此,我会添加一个评论给你的报价:

重构删除continue声明,使您的进一步重构能力。

内循环真的很好候选如提取function 。 当内部循环变得复杂时,这样的重构是完成的,然后continue可能使它变得痛苦。

这些是我在一个团队的JavaScript项目专业工作后的诚实意见,规则道格拉斯克罗克福德谈到真正显示其优点。

道格拉斯·克罗克福德可能会这样想,因为他不相信有条件的任务。 事实上,他的程序JSlint甚至不会让你这样做,即使Javascript。 他永远不会写:

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

这可能是他不喜欢继续的原因之一。

继续是一个非常有用的工具,可以节省algorithm中的计算周期。 当然,这可能是不正确的使用,但其他关键字或方法也可以使用。 在追求性能的时候,用条件语句对path散度采取逆方法是有用的。 继续可以通过允许在可能的情况下跳过效率较低的path来促进逆转。

其实从所有的分析看来,

  1. 如果你有浅循环 – 随意使用继续iff它提高了可读性(也可能有一些性能增益?)。
  2. 如果你有深嵌套循环(这意味着当你重新考虑时你已经有一个毛球解开),从代码可靠性的angular度来看,避免继续可能被certificate是有益的。

为了保护道格拉斯·克罗克福德,我觉得他的build议倾向于倾向于防御性的编程 ,这在所有的诚实方面似乎都是企业中“防白痴”的好方法。

就我个人而言,我从来没有听说过使用continue语句的不好之处。 确实可以(大部分时间)容易避免,但是没有理由使用它。 我发现,使用继续语句,循环可以更清晰,更具可读性。