有没有办法避免在Coffeescript中使用'call'?

时间:2011-05-28 18:03:13

标签: function call this coffeescript

我正在写一个简单的Twitter客户端来玩coffeescript。我有一个对象文字,其中一些函数通过回调相互调用。

somebject =
  foo: 'bar'
  authenticateAndGetTweets: ->
    console.log "Authorizing using oauth"
    oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails)
    oauth.authorize( this.afterLogin.call this )
  afterLogin: ->
    this.getTweets(this.pollinterval)

此代码完美无缺。 编辑:实际上this.afterlogin应作为回调发送,而不是立即运行,如Trevor所述。

如果在authenticateAndGetTweets中删除了'call'并且刚刚运行:

oauth.authorize( this.afterLogin )

并且不使用'call',我收到以下错误:

Uncaught TypeError: Object [object DOMWindow] has no method 'getTweets

这是有道理的,因为afterLogin中的'this'绑定到启动回调的东西而不是'someobject'我的对象文字。

我想知道Coffeescript中是否有一些魔法我可以做而不是'打电话'。最初我认为使用'=>'但如果'=>'代码将给出与上面相同的错误使用。

那么有什么方法可以避免使用呼叫?或者coffeescript不能消除它的需要吗?是什么造成'=>'没工作我的预期如何?

感谢。到目前为止,我真的非常喜欢咖啡,并希望确保我以正确的方式做事。

3 个答案:

答案 0 :(得分:3)

你可以将lambda放在函数调用中,如此

auth.authorize(=> @afterLogin())

答案 1 :(得分:3)

正如matyr在他的评论中指出的那样,行

oauth.authorize( this.afterLogin.call this )

不会导致this.afterLoginoauth.authorize作为回调调用;相反,它相当于

oauth.authorize this.afterLogin()

假设您希望this.afterLoginoauth.authorize用作回调,megakorre的回答会提供正确的CoffeeScript习惯用法。正如matyr指出的那样,许多现代JS环境支持的另一种方法是编写

oauth.authorize( this.afterLogin.bind this )

没有CoffeeScript的简写,部分原因是所有主流浏览器都不支持Function::bind。您还可以使用Underscore.js等库中的bind函数:

oauth.authorize( _.bind this.afterLogin, this )

最后,如果您要将someobject定义为类,则可以使用=>来定义afterLogin,以便它始终绑定到实例,例如

class SomeClass
  foo: 'bar'
  authenticateAndGetTweets: ->
    console.log "Authorizing using oauth"
    oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails)
    oauth.authorize(this.afterLogin)
  afterLogin: =>
    this.getTweets(this.pollinterval)

someobject = new SomeClass

答案 2 :(得分:0)

您必须使用call或apply方法,因为它们设置了函数的范围(this的值)。错误的结果是因为默认范围是window对象。