如何在Coffeescript对象缩进中正确使用'for..in'列表理解?

时间:2011-12-25 11:09:09

标签: syntax coffeescript list-comprehension idiomatic

我刚刚开始使用Coffeescript,所以我可能会问一些非常微不足道的事情,但这个“bug”最近让我感到高兴:

class Foo
  toJSON_1: ->
    title: 'toJSON_1'
    items: i for i in [1..5]

  toJSON_2: ->
    items: i for i in [1..5]
    title: 'toJSON_2'

  toJSON_3: ->
    items: (i for i in [1..5])
    title: 'toJSON_3'

foo = new Foo
console.log(foo.toJSON_1())
console.log(foo.toJSON_2())
console.log(foo.toJSON_3())

我会考虑所有这些equivelant,但看看JSON_2会发生什么:

{ title: 'toJSON_1', items: [ 1, 2, 3, 4, 5 ] }
{ title: 'toJSON_2' }
{ items: [ 1, 2, 3, 4, 5 ], title: 'toJSON_3' }

调试需要一段时间,因为我使用符号JSON_1跟随教程,但在我的代码中,列表理解不是最后一项(即JSON_2),直到我绊倒在测试JSON_3

有人可以向我解释为什么CoffeeScript解析器以这种方式工作吗?在一般情况下,什么是正确的习语?我应该总是将列表理解包含在parens中吗?听起来像一个等待发生的错误总是假设只有一个列表理解,它将在对象声明的末尾。

也许这只是我不知道的解析器规则的特殊情况......?

修改

使用编译器并生成更多Javascript,看起来它足以将代码包装在Coffeescript的{}括号中以执行正确的事情

 toJSON_2: ->
   {
     items: i for i in [1..5]
     title: 'toJSON_2
   }

我想我的问题归结为:

  • 使用{}括号或括号是更惯用的 列表理解周围?
  • 这种“不可预测”的行为是一个错误吗?
  • 如果没有,为什么不呢?

3 个答案:

答案 0 :(得分:3)

建议在构建数组时在括号中包含推理,因为items = (item for item in list when x is y)

toJSON_2中,第一行被解释为

{ items: i } for i in [1..5]

你不能因此而责怪咖啡因,因为目的不明确。我的建议是遵循一个简单的指导原则:任何会让人混淆的事情很可能会使解析器混淆

包括在括号中包装表达式,使用显式return s,对象文字的括号,临时变量以及在代码中明确表达意图所需的任何内容。

答案 1 :(得分:1)

过早修复#1871#1903的后果。

答案 2 :(得分:0)

这是我作为程序员的观点,但不是那个实际使用过CoffeeScript的人(对我来说已经相当深入了解):编程时,你的一般努力应该是做出意义你的代码尽可能明显而且毫不含糊(虽然也可能有其他重要的东西,所以这并不总是最重要的目标)。

当你遇到像这样的令人讨厌的地区(一些CoffeeScript的人会知道,有些人不会 - 在这种情况下,我碰巧在尝试使用它之前对CoffeeScript进行研究时已经读过它),卷曲大括号使它很多更明显,更明确无误。而对于另一个,你留下了一个脆弱的结构,初学者会做一个看似完全无害的改变,但它将彻底打破它(你可能没有意识到它,然后调试非常困难)。