为什么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来促进逆转。
其实从所有的分析看来,
- 如果你有浅循环 – 随意使用继续iff它提高了可读性(也可能有一些性能增益?)。
- 如果你有深嵌套循环(这意味着当你重新考虑时你已经有一个毛球解开),从代码可靠性的angular度来看,避免继续可能被certificate是有益的。
为了保护道格拉斯·克罗克福德,我觉得他的build议倾向于倾向于防御性的编程 ,这在所有的诚实方面似乎都是企业中“防白痴”的好方法。
就我个人而言,我从来没有听说过使用continue语句的不好之处。 确实可以(大部分时间)容易避免,但是没有理由不使用它。 我发现,使用继续语句,循环可以更清晰,更具可读性。