I'm having a problem with what the browser considers 'this' to be. In the following example, calling pingMe() on abc will wait 1 second and then the browser will say that Object DOMWindow has no method 'func'. Instead of resolving 'this' to the instance of class ABC (abc), it instead resolves to the DOMWindow, as if the object wasn't involved. I'm clearly not understanding how setTimeout works with respect to callback scope. Any suggestions how i can make this callback succeed?
class ABC
@func = null
constructor: (func) ->
@func = func
pingMe: ->
setTimeout(doPing, 1000)
doPing = ->
@func()
abc = new ABC ->
alert "HI"
abc.pingMe()
I got this code working.
class ABC
@func = null
constructor: (func) ->
@func = func
pingMe: ->
setTimeout =>
@doPing()
, 1000
doPing: ->
@func()
abc = new ABC ->
alert "HI"
abc.pingMe()
Your doPing method was defined doPing = ->
, whereas the others all use name: ->
, I changed it that way. pingMe
uses =>
to create a unnamed function, and @doPing
to bind this
to the function.
Not sure if this is correct, I rarely use JavaScript. But I hope it might give you a direction to look further.
An alternative solution which is closer to what you would do in ES5 is:
pingMe: ->
setTimeout(@doPing.bind(@), 1000)
or if you want to save on parentheses:
pingMe: ->
setTimeout (@doPing.bind @), 1000
Note that bind
is ES5, so only available in IE from version 9.
Also note, you should at all costs avoid the temptation to try:
setTimeout(@doPing.bind @, 1000) # BAD!
or
setTimeout @doPing.bind @, 1000 # BAD!
because both of those pass the number as the second argument to bind
, not setTimeout
!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With