2012-07-07 18 views
5
class Game 

    foo: null 

    play: -> 

    @foo = 2 
    @animate() 

    animate: -> 

    requestAnimationFrame(@animate, 1000) 
    console.log('foo = ', @foo) 


$ -> 
    game = null 

    init = -> 

    game = new Game() 
    game.play() 

    init() 

Dziennik w metodzie ożywionej w Grze produkuje:zmiennej instancji zostaje niezdefiniowany - coffeescript

foo = 2

foo = niezdefiniowany

Więc foo jest 2 na pierwsze wezwanie do animowania a następnie niezdefiniowane. Czy ktoś mógłby wyjaśnić, dlaczego i jak mogę to naprawić? Każda pomoc jest doceniana.

+0

'requestAnimationFrame' nie przyjmuje liczby jako drugiego argumentu; zamiast tego wywołuje daną funkcję ASAP (zwykle działa szybciej niż "setTimeout (func, 0)") pod warunkiem, że karta przeglądarki znajduje się na pierwszym planie. Zobacz https://developer.mozilla.org/en/DOM/window.requestAnimationFrame –

Odpowiedz

11

Po wywołaniu setInterval, kontekst zostaje utracony, a po raz drugi @ jest window. Musisz metody tłuszczu strzałek, aby zachować odpowiednią this:

animate: => 
+0

Dziękuję za odpowiedź. To zadziałało, ale spowodowało bardzo dziwne zachowanie z requestAnimationFrame. Nazywam requestAnimationFrame, tak jak powinno, ale z grubą strzałką jest to rodzaj powtarzania połączenia przez drugie wywołanie requestAnimationFrame. –

+0

@ user881920 To powtórzenie jest poprawnym zachowaniem. Powinieneś przyjąć odpowiedź Aarona. Jeśli masz problem z 'requestAnimationFrame', powinieneś zadać osobne pytanie na ten temat. –

+0

Dziękuję za tę odpowiedź. Prosty i jasny. – Glenn

5

Można zdefiniować animate następująco:

animate: -> 
    callback = (=> @animate()) 
    requestAnimationFrame(callback, 1000) 
    console.log('foo = ', @foo) 

Technika tutaj jest, aby sposób związany. @animate samo w sobie jest niezwiązane, ale (=> @animate()) jest związaną wersją tego.

Można uzyskać podobne rezultaty jeśli używasz underscore.js następująco:

animate: -> 
    callback = _.bind(@animate, @) 
    requestAnimationFrame(callback, 1000) 
    console.log('foo = ', @foo) 

A jeśli używasz nowszej wersji języka JavaScript, możesz to zrobić w następujący sposób:

animate: -> 
    callback = @animate.bind(@) 
    requestAnimationFrame(callback, 1000) 
    console.log('foo = ', @foo) 
Powiązane problemy