1

次のコードがあります

class Foo 

  a: ->
    console.log arguments.callee.name

  b: ->
    @a()

  c: ->
    @a()


f = new Foo
f.b() #=> should output 'b'
f.c() #=> should output 'c'

質問: クラス内の呼び出し関数の名前を取得するにはどうすればよいですか?


ユースケースはこちら

class Something extends Stream

  foo: ->
    _helper 'foo', 'a', 'b', 'c'

  bar: ->
    _helper 'bar', 'my neighbor totoro'

  dim: ->
    _helper 'dim', 1, 2, 3

  sum: ->
    _helper 'sum', 'hello', 'world'

  _helper: (command, params...) ->
    @emit 'data', command, params...

something = new Something
something.foo()
something.bar()
# ...

_helperプライベートメソッドへの呼び出しごとにメソッド名を重複して送信する必要はありません。

4

2 に答える 2

1

これは私がしたであろうことです:

class Something extends Stream
    constructor: ->
        @foo = helper.bind @, "foo", "a", "b", "c"
        @bar = helper.bind @, "bar", "my neighbor totoro"
        @dim = helper.bind @, "dim", 1, 2, 3
        @sum = helper.bind @, "sum", "hello", "world"

    helper = (command, params...) ->
        @emit 'data', command, params...

この方法の利点は次のとおりです。

  1. helper関数はプライベート変数です。インスタンスを介して直接アクセスすることはできません。
  2. helper関数は一度だけ宣言され、すべてのインスタンス間で共有されます。
  3. 関数foo、、、およびは、bar部分適用です。したがって、関数本体のためにより多くのメモリを消費することはありません。dimsumhelper
  4. @loganfsmythの答えのようにループは必要ありません。
  5. きれいです。

編集:さらにクリーンなアプローチは次のようになります:

class Something extends Stream
    constructor: ->
        @foo = @emit.bind @, "data", "foo", "a", "b", "c"
        @bar = @emit.bind @, "data", "bar", "my neighbor totoro"
        @dim = @emit.bind @, "data", "dim", 1, 2, 3
        @sum = @emit.bind @, "data", "sum", "hello", "world"

確かに、それは少し冗長ですが、JavaScriptのような言語からこれ以上期待することはできません。ファクターではありません。しかし、それは読みやすく、きれいで、簡単に理解でき、そして何よりも正しいです。

于 2012-12-16T02:41:09.347 に答える
1

明確にするために、2番目の方法は完全に合理的であり、進むべき道だと思います。

ただし、質問に答えるために、各関数を動的に生成して、コマンドを再入力する必要がないようにすることができます。

class Foo
  commands =
    foo: ['a', 'b', 'c']
    bar: ['my neighbor totoro']
    dim: [1,2,3]

  for own name, args of commands
    Foo::[name] = ->
      @emit 'data', name, args...

関数を便利なものにしたいと仮定すると、引き続き関数を使用できます。

// ...
  commands =
    foo: (args...) -> return ['a', 'b', 'c']
    // ...

  for own name, cb of commands
    Foo::[name] = (command_args...) ->
      args = cb.apply @, command_args
      @emit 'data', name, args...
于 2012-12-16T02:04:45.393 に答える