Coffeescript, эквивалентный getattr Python - PullRequest
3 голосов
/ 01 сентября 2011

В Python я могу поместить функцию в переменную во время выполнения, а затем вызвать ее с помощью функции getattr

method = getattr(self,self.name)
method()

Есть ли подобный способ сделать это в Coffeescript?Спасибо!


Использование предложения Zeekay, но с использованием классов:

class Test
   foo: -> alert 'foo'
   foo2: methodName -> this[methodName]()

x = new Test
x.foo2('foo')

Ответы [ 5 ]

11 голосов
/ 01 сентября 2011

В Javascript объекты являются ассоциативными массивами, и вы можете получить доступ к свойству / методам, используя имя свойства в качестве ключа:

obj =
  method: -> 'xxx'
method = obj['method']
method() # 'xxx'

Ваш обновленный пример не работает, потому что foo2 просто возвращает foo. Вы можете попробовать это:

class Test
   foo: -> alert 'foo'
   foo2: -> this['foo']() # or @['foo']()

x = new Test
x.foo2()
2 голосов
/ 01 сентября 2011

Объекты и классы в CoffeeScript работают совсем не так, как в Python. Это может быть неприятно, но цель CoffeeScript - оставаться как можно ближе к JavaScript, а не добавлять толстый слой абстракции. Итак, несколько вещей, которые нужно иметь в виду:

  1. Как ответил zeekay, x[y] эквивалентно getattr / setattr (за исключением того, что возвращается undefined, если x не имеет свойства с ключом y, вместо того, чтобы выдавать исключение);
  2. Функции, которые вы присоединяете к классу с использованием синтаксиса foo: -> ..., являются просто методами прототипа класса и могут быть изменены в любое время (или переопределены в конкретном экземпляре).
  3. После выполнения method = x.method между x.method() и method() есть одно существенное различие, даже при том, что оба запускают одну и ту же функцию: Когда вы запускаете функцию как x.method(), this указывает на x; но когда вы запускаете его как method(), this указывает на глобальный объект (window в браузере, global в Node.js).

Посмотрите мою книгу, CoffeeScript: ускоренная разработка JavaScript , если вы хотите узнать больше. :) 1030 * *

1 голос
/ 01 сентября 2011
class Test
   foo: -> alert 'foo'
   foo2: -> this['foo']

Когда вы звоните x.foo2() он не делает то, что вы думаете, он делает.

-> this['foo']

Эта функция возвращает значение this['foo'], которое является функциональным объектом. Таким образом, возвращаемое значение является функциональным объектом. Функция не запускается.

Попробуйте это:

class Test
   foo: -> alert 'foo'
   foo2: -> this['foo']()

Теперь при вызове foo2() он получает объект funciton и выполняет его .


Кроме того, при использовании динамической строки в качестве средства доступа вам нужно использовать только скобочные обозначения. Это одно и то же:

class Test
   foo: -> alert 'foo'
   foo2: -> @foo()
1 голос
/ 01 сентября 2011

Похоже, что это да, но вы должны использовать жирную стрелку в определении метода:

class O
    method2 =>
        console.log(this)

Если я правильно понимаю, этот синтаксис говорит coffeescript связать экземпляр с методом, позволяя вызывать его извне экземпляра. Если вы используете тонкую стрелку, coffeescript не отслеживает информацию о привязке, в результате чего Javascript указывает this на что-то неожиданное, если вы не вызываете метод через экземпляр.

class O
    method2 ->
        console.log(this)
1 голос
/ 01 сентября 2011

Ваш foo2 возвращает метод foo для его вызова. Изменение

return this['foo'];

до:

this['foo']();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...