我正在写一个简单的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不能消除它的需要吗?是什么造成'=>'没工作我的预期如何?
感谢。到目前为止,我真的非常喜欢咖啡,并希望确保我以正确的方式做事。
答案 0 :(得分:3)
你可以将lambda放在函数调用中,如此
auth.authorize(=> @afterLogin())
答案 1 :(得分:3)
正如matyr在他的评论中指出的那样,行
oauth.authorize( this.afterLogin.call this )
不会导致this.afterLogin
将oauth.authorize
作为回调调用;相反,它相当于
oauth.authorize this.afterLogin()
假设您希望this.afterLogin
被oauth.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
对象。