Есть ли способ избежать использования 'call' в Coffeescript? - PullRequest
4 голосов
/ 28 мая 2011

Я пишу простой 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 должен быть отправлен как обратный вызов выше, а не сразу, как Тревор заметил ниже.

Если в authenticateAndGetTweets я удалил 'call' и просто запустил:

oauth.authorize( this.afterLogin )

и не использовал 'call', я получил бы следующую ошибку:

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

Что имеет смысл, поскольку «this» в afterLogin связано с тем, что инициировало обратный вызов, а не с «someobject» литералом моего объекта.

Мне было интересно, есть ли какая-нибудь магия в Coffeescript, которую я мог бы делать вместо 'call'.Первоначально я думал использовать '=>', но код выдаст ту же ошибку, что и выше, если используется '=>'.

Так есть ли способ избежать вызова?Или coffeescript не устраняет необходимость в этом?Что заставило '=>' работать не так, как я ожидал?

Спасибо.Я до сих пор наслаждаюсь coffeescript и хочу быть уверенным, что делаю все «правильно».

Ответы [ 3 ]

3 голосов
/ 28 мая 2011

вы можете поместить лямбду в вызов функции следующим образом:

auth.authorize(=> @afterLogin())
3 голосов
/ 29 мая 2011

Как указывает Матыр в своих комментариях, строка

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 поддерживается не всеми основными браузерами.Вы также можете использовать функцию 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
0 голосов
/ 28 мая 2011

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

...