为什么|| =不编译,如果我们在coffeescript中使用[]或不使用?

时间:2014-09-29 15:25:01

标签: coffeescript

为什么会出现这种差异:

class Foo
  getTest: ->
    @test ||= 42

编译为:

return this.test || (this.test = 42);

不同的

class Foo
  getTest: ->
    @test['bar'] ||= 42

编译在:

var _base;
return (_base = this.test)['bar'] || (_base['bar'] = 42);

这个变量" _base"?!

的用处是什么?
return this.test['bar'] || (this.test['bar'] = 42);

也是一个好方法,不是吗?

THX。

1 个答案:

答案 0 :(得分:2)

||=需要考虑两大类结构:

simple_expr  ||= x
complex_expr ||= x

简单表达式类似于@test :(可能)没有副作用,并且(可能)没有性能损失来评估它两次。

复杂表达式将是其他任何内容:@test['x']@test(11).pancakes,...复杂表达式可能有副作用或可能很昂贵,因此您只想评估它们一次。

现在考虑评估expr1的次数:

expr1 || (expr1 = expr2)

有时会expr1评估两次,因此CoffeeScript会尽可能多地expr1隐藏_base,以避免两次评估expr1的费用和可能的副作用

您可能还会注意到,对于简单的表达式,只有隐藏在_base中的东西才是整个表达式本身。我怀疑他们实际上默认是考虑到所有表达方式都很复杂,然后当发现没有任何内容隐藏在其中时遗漏_base