如果我有一个复杂的If语句,我不想仅仅出于美观的目的而溢出,那么在这种情况下,由于coffeescript将把返回值解释为语句体,因此将其分解的最合适的方法是什么?
if (foo is bar.data.stuff and foo isnt bar.data.otherstuff) or (not foo and not bar)
awesome sauce
else lame sauce
如果下一行以操作符结尾,CoffeeScript将不会将下一行解释为语句体,所以这是可以的:
# OK!
if a and
not
b
c()
编译成
if (a && !b) {
c();
}
所以你的if
可以被格式化为
# OK!
if (foo is
bar.data.stuff and
foo isnt bar.data.otherstuff) or
(not foo and not bar)
awesome sauce
else lame sauce
或任何其他断行方案,只要行以and
或or
或is
或==
或not
或其他诸如此类的操作符
至于缩进,你可以缩进if
的非第一行,只要正文更缩进:
# OK!
if (foo is
bar.data.stuff and
foo isnt bar.data.otherstuff) or
(not foo and not bar)
awesome sauce
else lame sauce
你不能这样做:
# BAD
if (foo #doesn't end on operator!
is bar.data.stuff and
foo isnt bar.data.otherstuff) or
(not foo and not bar)
awesome sauce
else lame sauce
这在一定程度上改变了代码的含义,但可能有一些用途:
return lame sauce unless foo and bar
if foo is bar.data.stuff isnt bar.data.otherstuff
awesome sauce
else
lame sauce
注意is...isnt
链,它是合法的,就像a < b < c
在CoffeeScript中是合法的一样。当然,重复lame sauce
是不幸的,您可能不希望立即执行return
。另一种方法是使用soaks写入
data = bar?.data
if foo and foo is data?.stuff isnt data?.otherstuff
awesome sauce
else
lame sauce
if foo and
有点不美观;如果foo
不可能是undefined
,则可以丢弃它。
就像其他语言一样,从一开始就没有它们。给不同的部分命名,分开对待。可以声明谓词,也可以创建几个布尔值。
bar.isBaz = -> @data.stuff != @data.otherstuff
bar.isAwsome = (foo) -> @isBaz() && @data.stuff == foo
if not bar? or bar.isAwesome foo
awesome sauce
else lame sauce
转义换行对我来说是最易读的:
if (foo is bar.data.stuff and foo isnt bar.data.otherstuff)
or (not foo and not bar)
awesome sauce
else lame sauce
当出现大量低级别的样板文件时,您应该增加抽象级别。
最好的解决方案是:
-
使用命名好的变量和函数
-
逻辑规则if/else语句
逻辑规则之一是:
(not A and not B) == not (A or B)
第一种方式。
变量:isStuff = foo is bar.data.stuff
isntOtherStuff = foo isnt bar.data.otherstuff
isStuffNotOtherStuff = isStuff and isntOtherStuff
bothFalse = not (foo or bar)
if isStuffNotOtherStuff or bothFalse
awesome sauce
else lame sauce
这种方法的主要缺点是速度慢。如果我们使用and
和or
运算符特性,用函数代替变量,我们将获得更好的性能:
- C = A和B
如果A
为假,操作符and
不会调用
- C = A或B
如果A
为真,操作符or
不会调用
第二种方式。
功能:isStuff = -> foo is bar.data.stuff
isntOtherStuff = -> foo isnt bar.data.otherstuff
isStuffNotOtherStuff = -> do isStuff and do isntOtherStuff
bothFalse = -> not (foo or bar)
if do isStuffNotOtherStuff or do bothFalse
awesome sauce
else lame sauce