Coffeescript子类的静态继承

时间:2013-11-08 03:02:47

标签: coffeescript

这有效:

class Foo 
  class @_Bar 
    @narf = ''
    @point : ->
      @narf = 'what'

  class @_Baz extends @_Bar 
    @point : ->
      @narf = 'woo'
      super()

这不是

class Foo 
  class @_Bar 
    @narf = ''
    @point = ->
      @narf = 'what'

  class @_Baz extends @_Bar 
    @point = ->
      @narf = 'woo'
      super()

运行Foo._Baz.point()会抛出错误。


请有人解释这里发生的事情。

3 个答案:

答案 0 :(得分:3)

对我来说,这似乎是编译器中的一个错误。写

class X
  @classMethod: ->

class X
  @classMethod = ->

应该是等价的,但super在两种方法中编译的方式不同。首先,它正确编译:

X.__super__.constructor.classMethod.apply(this, arguments);

在第二个中,它编译好像classMethod是一个实例方法:

X.__super__.classMethod.apply(this, arguments);

答案 1 :(得分:2)

这有效:

class Foo 
  class @_Bar 
    @narf = ''
    point : ->
      @narf = 'what'

  class @_Baz extends @_Bar 
    @point = ->
      @narf = 'woo'
      super()

alert Foo._Baz.point()  # 'what'
alert new Foo._Bar().point() # 'what'

也就是说,编译后的@point= super最终指向实例point:。它的JS是:_Baz.__super__.point.call(this),即_Bar.prototype.point.call(this)。 (extends定义:child.__super__ = parent.prototype)。

从过去的Coffeescript更改可以清楚地看出,@point:是静态(类)方法的预期语法(并在编译器本身中以这种方式使用)。

答案 2 :(得分:1)

现在github上有几个修复程序。 https://github.com/jashkenas/coffee-script/issues/3232

目前,@foo=方法的节点树与@foo:方法的节点树不同。因此,使用=创建的节点永远不会传递给Class addParameters方法,也不会被标记为static

可能会接受一个解决方案,确保两个表单都生成相同的节点树。

我贡献的那个https://github.com/jashkenas/coffee-script/issues/3232#issuecomment-28316501nodes.coffee class Class添加方法。此方法是addParameters的精简版本,并专门检查=节点树。

如果您需要在自己的Coffee编译器中修复,请修改src/coffee-script/nodes.coffee文件,编译它,并将生成的node.js放在lib目录中(或使用{{1 }})。