javascript - Coffeescript equivalent to Python's getattr - Stack Overflow

In python I can put a function into a variable at runtime, then call it using the getattr functionmetho

In python I can put a function into a variable at runtime, then call it using the getattr function

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

Is there a similar way to do this in Coffeescript? Thanks!


Using zeekay suggestion but using classes would be:

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

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

In python I can put a function into a variable at runtime, then call it using the getattr function

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

Is there a similar way to do this in Coffeescript? Thanks!


Using zeekay suggestion but using classes would be:

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

x = new Test
x.foo2('foo')
Share Improve this question edited Sep 1, 2011 at 0:52 David Anderson asked Aug 31, 2011 at 23:36 David AndersonDavid Anderson 6235 silver badges22 bronze badges 3
  • With a workaround, yes. In Python, an instance method is bound to the instance, but in Javascript they are not. See s-anand/blog/bound-methods-in-javascript for more information. – Erik Youngren Commented Sep 1, 2011 at 0:11
  • Okay, see my answer and try this with the fat arrow: => – Erik Youngren Commented Sep 1, 2011 at 0:53
  • foo2: methodName -> this[methodName]() is not what you want. It's equivalent to foo2: methodName(-> this[methodName]()). That is, it passes the function -> this[methodName]() to a function called methodName, then assigns the result to the foo2 prototype property of the Test class. – Trevor Burnham Commented Sep 1, 2011 at 1:42
Add a ment  | 

5 Answers 5

Reset to default 11

In Javascript objects are associative arrays, and you can access property/methods using the name of the property as the key:

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

Your updated example doesn't work because foo2 is merely returning foo. You might want to try this:

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

x = new Test
x.foo2()

Objects and classes in CoffeeScript work very differently from how they work in Python. This can be frustrating, but the aim of CoffeeScript is to stay as close to JavaScript as possible, rather than adding a thick layer of abstraction. So, a few things to keep in mind:

  1. As zeekay answered, x[y] is equivalent to getattr/setattr (except that it returns undefined if x has no property with key y, rather than throwing an exception);
  2. Functions you attach to a class using the syntax foo: -> ... are just methods of the class' prototype, and can be modified at any time (or overridden on a particular instance).
  3. After running method = x.method, there's one crucial difference between x.method() and method(), even though both run the same function: When you run the function as x.method(), this points to x; but when you run it as method(), this points to the global object (window in the browser, global in Node.js).

Check out my book, CoffeeScript: Accelerated JavaScript Development, if you'd like to learn more. :)

Your foo2 returns the foo method intead of calling it. Change

return this['foo'];

to:

this['foo']();

It looks like this is a yes, but you have to use the fat arrow operator in the method definition:

class O
    method2 =>
        console.log(this)

If I understand this correctly, that syntax tells coffeescript to bind the instance to the method, allowing it to be called from outside the instance. If you use the thin arrow, coffeescript does not keep track of binding information, resulting in Javascript pointing this at something unexpected if you don't call the method via the instance.

class O
    method2 ->
        console.log(this)
class Test
   foo: -> alert 'foo'
   foo2: -> this['foo']

When you call x.foo2() it's not doing what you think it's doing.

-> this['foo']

This function returns the value of this['foo'] which is a function object. So the return value is a function object. It doesn't run the function.

Try this:

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

Now when call foo2() it get the funciton object and executes it.


Also though, you only need the bracket notation when using a dynamic string as an accessor. This is the exactly the same thing:

class Test
   foo: -> alert 'foo'
   foo2: -> @foo()

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743712294a4494394.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信