Как вызвать «супер» из обратного вызова в coffeescript - PullRequest
9 голосов
/ 28 июня 2011
class Foo
    a: ->
        x.call =>
            super

не скомпилируется, так как я не могу вызвать super из анонимного класса. Однако мой намерение состоит в том, чтобы вызвать метод суперкласса для 'a'. Это пропавший возможность в coffeescript?

Обратите внимание, что я изменяю код на

class Foo
    a: ->
        x.call =>
                return Foo.__super__.a.apply(this, arguments)

чтобы все заработало, но это не совсем правильно!

Ответы [ 3 ]

9 голосов
/ 29 июня 2011

Предлагаемое вами решение о написании Foo.__super__.a.apply(this, arguments), боюсь, в основном так же хорошо, как вы собираетесь получить.CoffeeScript позволяет писать такие вещи, как

a = ->
  b = ->
    super

(в этом случае super указывает на суперфункцию b), поэтому было бы немного странно иметь super в пределах

a: ->
  x =>
    super

указывает на суперфункцию a.Вы можете поднять вопрос, чтобы попросить разрешить это, однако.Это не двусмысленно с точки зрения компиляции, просто выглядит немного странно.

Вот кое-что, что вы можете попробовать сделать более элегантным:

class Foo
  constructor: ->
    @sup = Foo.__super__

  a: ->
    x =>
      @sup.a.apply this, arguments
1 голос
/ 04 апреля 2012

Я столкнулся с той же проблемой и решил ее так:

ChainSuper = (classType, memberName, useFatArrow) ->
  original = classType::[memberName]
  superf  = classType.__super__.constructor.prototype[memberName]
  callSuper = (thisRef, args, superArgs) ->
    for i in [0...superArgs.length]
      args[i] = superArgs[i]
    superf.apply thisRef, args

  classType::[memberName] = if useFatArrow
    (args...) ->
      original.call @, args..., (superArgs...) =>
        callSuper @, args, superArgs
  else
    (args...) ->
      original.call @, args..., (thisRef, superArgs...) ->
        callSuper thisRef, args, superArgs

Это очень некошерно и, вероятно, сломается, если семантика класса компилятора Coffeescript изменится. Однако в ожидании этого я могу сказать:

CheckSuper = (ref, message) ->
  if ref instanceof Superclass
    alert "Works with #{message}"

class Superclass
  plus: (values...) ->
    CheckSuper @, 'plus'
    @val = 0
    for i in values
      @val += i
    alert @val

  minusBase: 0
  minus: (values...) ->
    CheckSuper @, 'minus'
    @val = @minusBase
    for i in values
      @val -= i
    alert @val

class Subclass extends Superclass
  plus: (values..., Super) ->
    setTimeout (=> Super @), 0
  ChainSuper @, 'plus'

  minus: (values..., Super) =>
    @minusBase = values[0]
    setTimeout (-> Super values[1...]..., 0), 0
  ChainSuper @, 'minus', true


subInstance = new Subclass()
subInstance.plus 1, 2, 3, 4
minus = subInstance.minus
minus 100, 10, 1

Обратите внимание, что в этом решении, если вы передаете n аргументов в Super (), когда метод вызывается с более чем n аргументами, только первые n аргументов перезаписываются при вызове метода super, а остальные будет передано без изменений.

0 голосов
/ 14 ноября 2011

Теперь вы можете использовать супер :: () метод вместо этого.

...