Is there a way to avoid using 'call' in Coffeescript?

Refresh

December 2018

Views

2k time

4

I'm writing a simple Twitter client to play with coffeescript. I have an object literal with some functions that call each other via callbacks.

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 code works perfectly. Edit: actually this.afterlogin should be sent as a callback above, not ran immediately, as Trevor noted below.

If, within authenticateAndGetTweets, I removed the 'call' and just ran:

oauth.authorize( this.afterLogin )

and don't use 'call', I get the following error:

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

Which makes sense, since 'this' in afterLogin is bound to the thing that initiated the callback rather than 'someobject' my object literal.

I was wondering if there's some magic in Coffeescript I could be doing instead of 'call'. Initially I thought using the '=>' but the code will give the same error as above if '=>' is used.

So is there a way I can avoid using call? Or does coffeescript not obviate the need for it? What made '=>' not work how I expected it to?

Thanks. I'm really enjoying coffeescript so far and want to make sure I'm doing things 'the right way'.

3 answers

0

Вы должны использовать либо вызов или применять методы , поскольку они устанавливают сферу функции (значение этого). Погрешность результатов , поскольку сфера по умолчанию является windowобъектом.

Maz
3

Как matyr отмечает в своих комментариях, линия

oauth.authorize( this.afterLogin.call this )

не вызывает this.afterLoginназываться как обратный вызов с помощью oauth.authorize; вместо этого, это эквивалентно

oauth.authorize this.afterLogin()

Предполагая , что вы хотите , this.afterLoginчтобы использовать в качестве обратного вызова с помощью oauth.authorize, ответ megakorre дает правильный CoffeeScript идиомы. Альтернативный подход поддерживается многими современными средами JS, так как matyr указывает, должен был бы написать

oauth.authorize( this.afterLogin.bind this )

Там нет CoffeeScript стенографии для этого, отчасти потому , что Function::bindне поддерживается всеми основными браузерами. Вы можете также использовать bindфункцию из библиотеки , как Underscore.js :

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
3

Вы можете поставить лямбда в вызове функции, как так

auth.authorize(=> @afterLogin())